//
// Copyright (C) 2019 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/payload_properties.h"

#include <memory>
#include <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/rand_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/data_encoding.h>

#include <gtest/gtest.h>

#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/payload_generator/delta_diff_generator.h"
#include "update_engine/payload_generator/delta_diff_utils.h"
#include "update_engine/payload_generator/full_update_generator.h"
#include "update_engine/payload_generator/operations_generator.h"
#include "update_engine/payload_generator/payload_file.h"
#include "update_engine/payload_generator/payload_generation_config.h"

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

namespace chromeos_update_engine {

// TODO(kimjae): current implementation is very specific to a static way of
// producing a deterministic test. It would definitely be beneficial to
// extend the |PayloadPropertiesTest::SetUp()| into a generic helper or
// seperate class that can handle creation of different |PayloadFile|s.
class PayloadPropertiesTest : public ::testing::Test {
 protected:
  void SetUp() override {
    PayloadGenerationConfig config;
    config.version.major = kBrilloMajorPayloadVersion;
    config.version.minor = kSourceMinorPayloadVersion;
    PayloadFile payload;
    EXPECT_TRUE(payload.Init(config));

    const auto SetupPartitionConfig =
        [](PartitionConfig* config, const string& path, size_t size) {
          config->path = path;
          config->size = size;
        };
    const auto WriteZerosToFile = [](const char path[], size_t size) {
      string zeros(size, '\0');
      EXPECT_TRUE(utils::WriteFile(path, zeros.c_str(), zeros.size()));
    };
    ScopedTempFile old_part_file("old_part.XXXXXX");
    ScopedTempFile new_part_file("new_part.XXXXXX");
    PartitionConfig old_part(kPartitionNameRoot);
    PartitionConfig new_part(kPartitionNameRoot);
    SetupPartitionConfig(&old_part, old_part_file.path(), 0);
    SetupPartitionConfig(&new_part, new_part_file.path(), 10000);
    WriteZerosToFile(old_part_file.path().c_str(), old_part.size);
    WriteZerosToFile(new_part_file.path().c_str(), new_part.size);

    // Select payload generation strategy based on the config.
    unique_ptr<OperationsGenerator> strategy(new FullUpdateGenerator());

    vector<AnnotatedOperation> aops;
    off_t data_file_size = 0;
    ScopedTempFile data_file("temp_data.XXXXXX", true);
    BlobFileWriter blob_file_writer(data_file.fd(), &data_file_size);
    // Generate the operations using the strategy we selected above.
    EXPECT_TRUE(strategy->GenerateOperations(
        config, old_part, new_part, &blob_file_writer, &aops));

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

    uint64_t metadata_size;
    EXPECT_TRUE(payload.WritePayload(
        payload_file_.path(), data_file.path(), "", &metadata_size));
  }

  ScopedTempFile payload_file_{"payload_file.XXXXXX"};
};

// Validate the hash of file exists within the output.
TEST_F(PayloadPropertiesTest, GetPropertiesAsJsonTestHash) {
  constexpr char kJsonProperties[] =
      "{"
      R"("is_delta":true,)"
      R"("metadata_signature":"",)"
      R"("metadata_size":165,)"
      R"("metadata_size_str":"165",)"
      R"("sha256_hex":"cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=",)"
      R"("size":211,)"
      R"("size_str":"211",)"
      R"("version":2)"
      "}";
  string json;
  EXPECT_TRUE(
      PayloadProperties(payload_file_.path()).GetPropertiesAsJson(&json));
  EXPECT_EQ(kJsonProperties, json) << "JSON contents:\n" << json;
}

// Validate the hash of file and metadata are within the output.
TEST_F(PayloadPropertiesTest, GetPropertiesAsKeyValueTestHash) {
  constexpr char kKeyValueProperties[] =
      "FILE_HASH=cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=\n"
      "FILE_SIZE=211\n"
      "METADATA_HASH=aEKYyzJt2E8Gz8fzB+gmekN5mriotZCSq6R+kDfdeV4=\n"
      "METADATA_SIZE=165\n";
  string key_value;
  EXPECT_TRUE(PayloadProperties{payload_file_.path()}.GetPropertiesAsKeyValue(
      &key_value));
  EXPECT_EQ(kKeyValueProperties, key_value) << "Key Value contents:\n"
                                            << key_value;
}

}  // namespace chromeos_update_engine
