//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/payload_generator/delta_diff_generator.h"

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/logging.h>

#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/delta_performer.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/ab_generator.h"
#include "update_engine/payload_generator/blob_file_writer.h"
#include "update_engine/payload_generator/delta_diff_utils.h"
#include "update_engine/payload_generator/full_update_generator.h"
#include "update_engine/payload_generator/inplace_generator.h"
#include "update_engine/payload_generator/payload_file.h"

using std::string;
using std::unique_ptr;
using std::vector;

namespace chromeos_update_engine {

// bytes
const size_t kRootFSPartitionSize = static_cast<size_t>(2) * 1024 * 1024 * 1024;
const size_t kBlockSize = 4096;  // bytes

bool GenerateUpdatePayloadFile(
    const PayloadGenerationConfig& config,
    const string& output_path,
    const string& private_key_path,
    uint64_t* metadata_size) {
  if (!config.version.Validate()) {
    LOG(ERROR) << "Unsupported major.minor version: " << config.version.major
               << "." << config.version.minor;
    return false;
  }

  // Create empty payload file object.
  PayloadFile payload;
  TEST_AND_RETURN_FALSE(payload.Init(config));

  const string kTempFileTemplate("CrAU_temp_data.XXXXXX");
  string temp_file_path;
  int data_file_fd;
  TEST_AND_RETURN_FALSE(
      utils::MakeTempFile(kTempFileTemplate, &temp_file_path, &data_file_fd));
  ScopedPathUnlinker temp_file_unlinker(temp_file_path);
  TEST_AND_RETURN_FALSE(data_file_fd >= 0);

  {
    off_t data_file_size = 0;
    ScopedFdCloser data_file_fd_closer(&data_file_fd);
    BlobFileWriter blob_file(data_file_fd, &data_file_size);
    if (config.is_delta) {
      TEST_AND_RETURN_FALSE(config.source.partitions.size() ==
                            config.target.partitions.size());
    }
    PartitionConfig empty_part("");
    for (size_t i = 0; i < config.target.partitions.size(); i++) {
      const PartitionConfig& old_part =
          config.is_delta ? config.source.partitions[i] : empty_part;
      const PartitionConfig& new_part = config.target.partitions[i];
      LOG(INFO) << "Partition name: " << new_part.name;
      LOG(INFO) << "Partition size: " << new_part.size;
      LOG(INFO) << "Block count: " << new_part.size / config.block_size;

      // Select payload generation strategy based on the config.
      unique_ptr<OperationsGenerator> strategy;
      // We don't efficiently support deltas on squashfs. For now, we will
      // produce full operations in that case.
      if (!old_part.path.empty() &&
          !diff_utils::IsSquashfs4Filesystem(new_part.path)) {
        // Delta update.
        if (config.version.minor == kInPlaceMinorPayloadVersion) {
          LOG(INFO) << "Using generator InplaceGenerator().";
          strategy.reset(new InplaceGenerator());
        } else {
          LOG(INFO) << "Using generator ABGenerator().";
          strategy.reset(new ABGenerator());
        }
      } else {
        LOG(INFO) << "Using generator FullUpdateGenerator().";
        strategy.reset(new FullUpdateGenerator());
      }

      vector<AnnotatedOperation> aops;
      // Generate the operations using the strategy we selected above.
      TEST_AND_RETURN_FALSE(strategy->GenerateOperations(config,
                                                         old_part,
                                                         new_part,
                                                         &blob_file,
                                                         &aops));

      // Filter the no-operations. OperationsGenerators should not output this
      // kind of operations normally, but this is an extra step to fix that if
      // happened.
      diff_utils::FilterNoopOperations(&aops);

      TEST_AND_RETURN_FALSE(payload.AddPartition(old_part, new_part, aops));
    }
  }

  LOG(INFO) << "Writing payload file...";
  // Write payload file to disk.
  TEST_AND_RETURN_FALSE(payload.WritePayload(output_path, temp_file_path,
                                             private_key_path, metadata_size));

  LOG(INFO) << "All done. Successfully created delta file with "
            << "metadata size = " << *metadata_size;
  return true;
}

};  // namespace chromeos_update_engine
