//
// Copyright (C) 2015 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.
//

#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
#define UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_

#include <string>
#include <vector>

#include <base/macros.h>
#include <brillo/secure_blob.h>

#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/blob_file_writer.h"
#include "update_engine/payload_generator/extent_utils.h"
#include "update_engine/payload_generator/filesystem_interface.h"
#include "update_engine/payload_generator/operations_generator.h"
#include "update_engine/payload_generator/payload_generation_config.h"
#include "update_engine/update_metadata.pb.h"

namespace chromeos_update_engine {

// The ABGenerator is an operations generator that generates payloads using the
// A-to-B operations SOURCE_COPY and SOURCE_BSDIFF introduced in the payload
// minor version 2 format.
class ABGenerator : public OperationsGenerator {
 public:
  ABGenerator() = default;

  // Generate the update payload operations for the given partition using
  // SOURCE_* operations, used for generating deltas for the minor version
  // kSourceMinorPayloadVersion. This function will generate operations in the
  // partition that will read blocks from the source partition in random order
  // and write the new image on the target partition, also possibly in random
  // order. The operations are stored in |aops| and should be executed in that
  // order. All the offsets in the operations reference the data written to
  // |blob_file|.
  bool GenerateOperations(
      const PayloadGenerationConfig& config,
      const PartitionConfig& old_part,
      const PartitionConfig& new_part,
      BlobFileWriter* blob_file,
      std::vector<AnnotatedOperation>* aops) override;

  // Split the operations in the vector of AnnotatedOperations |aops|
  // such that for every operation there is only one dst extent and updates
  // |aops| with the new list of operations. All kinds of operations are
  // fragmented except BSDIFF and SOURCE_BSDIFF operations.
  // The |target_part_path| is the filename of the new image, where the
  // destination extents refer to. The blobs of the operations in |aops| should
  // reference |blob_file|. |blob_file| are updated if needed.
  static bool FragmentOperations(const PayloadVersion& version,
                                 std::vector<AnnotatedOperation>* aops,
                                 const std::string& target_part_path,
                                 BlobFileWriter* blob_file);

  // Takes a vector of AnnotatedOperations |aops| and sorts them by the first
  // start block in their destination extents. Sets |aops| to a vector of the
  // sorted operations.
  static void SortOperationsByDestination(
      std::vector<AnnotatedOperation>* aops);

  // Takes an SOURCE_COPY install operation, |aop|, and adds one operation for
  // each dst extent in |aop| to |ops|. The new operations added to |ops| will
  // have only one dst extent. The src extents are split so the number of blocks
  // in the src and dst extents are equal.
  // E.g. we have a SOURCE_COPY operation:
  //   src extents: [(1, 3), (5, 1), (7, 1)], dst extents: [(2, 2), (6, 3)]
  // Then we will get 2 new operations:
  //   1. src extents: [(1, 2)], dst extents: [(2, 2)]
  //   2. src extents: [(3, 1),(5, 1),(7, 1)], dst extents: [(6, 3)]
  static bool SplitSourceCopy(const AnnotatedOperation& original_aop,
                              std::vector<AnnotatedOperation>* result_aops);

  // Takes a REPLACE, REPLACE_BZ or REPLACE_XZ operation |aop|, and adds one
  // operation for each dst extent in |aop| to |ops|. The new operations added
  // to |ops| will have only one dst extent each, and may be of a different
  // type depending on whether compression is advantageous.
  static bool SplitAReplaceOp(const PayloadVersion& version,
                              const AnnotatedOperation& original_aop,
                              const std::string& target_part,
                              std::vector<AnnotatedOperation>* result_aops,
                              BlobFileWriter* blob_file);

  // Takes a sorted (by first destination extent) vector of operations |aops|
  // and merges SOURCE_COPY, REPLACE, REPLACE_BZ and REPLACE_XZ, operations in
  // that vector.
  // It will merge two operations if:
  //   - They are both REPLACE_*, or they are both SOURCE_COPY,
  //   - Their destination blocks are contiguous.
  //   - Their combined blocks do not exceed |chunk_blocks| blocks.
  // Note that unlike other methods, you can't pass a negative number in
  // |chunk_blocks|.
  static bool MergeOperations(std::vector<AnnotatedOperation>* aops,
                              const PayloadVersion& version,
                              size_t chunk_blocks,
                              const std::string& target_part,
                              BlobFileWriter* blob_file);

  // Takes a vector of AnnotatedOperations |aops|, adds source hash to all
  // operations that have src_extents.
  static bool AddSourceHash(std::vector<AnnotatedOperation>* aops,
                            const std::string& source_part_path);

 private:
  // Adds the data payload for a REPLACE/REPLACE_BZ/REPLACE_XZ operation |aop|
  // by reading its output extents from |target_part_path| and appending a
  // corresponding data blob to |blob_file|. The blob will be compressed if this
  // is smaller than the uncompressed form, and the operation type will be set
  // accordingly. |*blob_file| will be updated as well. If the operation happens
  // to have the right type and already points to a data blob, nothing is
  // written. Caller should only set type and data blob if it's valid.
  static bool AddDataAndSetType(AnnotatedOperation* aop,
                                const PayloadVersion& version,
                                const std::string& target_part_path,
                                BlobFileWriter* blob_file);

  DISALLOW_COPY_AND_ASSIGN(ABGenerator);
};

}  // namespace chromeos_update_engine

#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
