/*
 * 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 <stdint.h>
#include <stdio.h>

#include <map>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <bsdiff/bsdiff.h>
#include <gtest/gtest.h>
#include <ziparchive/zip_writer.h>

#include "otautil/paths.h"
#include "otautil/print_sha1.h"
#include "updater/blockimg.h"
#include "updater/build_info.h"
#include "updater/install.h"
#include "updater/simulator_runtime.h"
#include "updater/target_files.h"
#include "updater/updater.h"

using std::string;

// echo -n "system.img" > system.img && img2simg system.img sparse_system_string_.img 4096 &&
// hexdump -v -e '"    " 12/1 "0x%02x, " "\n"' sparse_system_string_.img
// The total size of the result sparse image is 4136 bytes; and we can append 0s in the end to get
// the full image.
constexpr uint8_t SPARSE_SYSTEM_HEADER[] = {
  0x3a, 0xff, 0x26, 0xed, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x00,
  0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xca,
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x73, 0x79, 0x73, 0x74, 0x65,
  0x6d, 0x2e, 0x69, 0x6d, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

static void AddZipEntries(int fd, const std::map<string, string>& entries) {
  FILE* zip_file = fdopen(fd, "w");
  ZipWriter writer(zip_file);
  for (const auto& pair : entries) {
    ASSERT_EQ(0, writer.StartEntry(pair.first.c_str(), 0));
    ASSERT_EQ(0, writer.WriteBytes(pair.second.data(), pair.second.size()));
    ASSERT_EQ(0, writer.FinishEntry());
  }
  ASSERT_EQ(0, writer.Finish());
  ASSERT_EQ(0, fclose(zip_file));
}

static string CalculateSha1(const string& data) {
  uint8_t digest[SHA_DIGEST_LENGTH];
  SHA1(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), digest);
  return print_sha1(digest);
}

static void CreateBsdiffPatch(const string& src, const string& tgt, string* patch) {
  TemporaryFile patch_file;
  ASSERT_EQ(0, bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(src.data()), src.size(),
                              reinterpret_cast<const uint8_t*>(tgt.data()), tgt.size(),
                              patch_file.path, nullptr));
  ASSERT_TRUE(android::base::ReadFileToString(patch_file.path, patch));
}

static void RunSimulation(std::string_view src_tf, std::string_view ota_package, bool expected) {
  TemporaryFile cmd_pipe;
  TemporaryFile temp_saved_source;
  TemporaryFile temp_last_command;
  TemporaryDir temp_stash_base;

  Paths::Get().set_cache_temp_source(temp_saved_source.path);
  Paths::Get().set_last_command_file(temp_last_command.path);
  Paths::Get().set_stash_directory_base(temp_stash_base.path);

  // Configure edify's functions.
  RegisterBuiltins();
  RegisterInstallFunctions();
  RegisterBlockImageFunctions();

  // Run the update simulation and check the result.
  TemporaryDir work_dir;
  BuildInfo build_info(work_dir.path);
  ASSERT_TRUE(build_info.ParseTargetFile(src_tf, false));
  Updater updater(std::make_unique<SimulatorRuntime>(&build_info));
  ASSERT_TRUE(updater.Init(cmd_pipe.release(), ota_package, false));
  ASSERT_EQ(expected, updater.RunUpdate());
  // TODO(xunchang) check the recovery&system has the expected contents.
}

class UpdateSimulatorTest : public ::testing::Test {
 protected:
  void SetUp() override {
    std::vector<string> props = {
      "import /oem/oem.prop oem*",
      "# begin build properties",
      "# autogenerated by buildinfo.sh",
      "ro.build.id=OPR1.170510.001",
      "ro.build.display.id=OPR1.170510.001 dev-keys",
      "ro.build.version.incremental=3993052",
      "ro.build.version.release=O",
      "ro.build.date=Wed May 10 11:10:29 UTC 2017",
      "ro.build.date.utc=1494414629",
      "ro.build.type=user",
      "ro.build.tags=dev-keys",
      "ro.build.flavor=angler-user",
      "ro.product.system.brand=google",
      "ro.product.system.name=angler",
      "ro.product.system.device=angler",
    };
    build_prop_string_ = android::base::Join(props, "\n");

    fstab_content_ = R"(
#<src>         <mnt_point>  <type>  <mnt_flags and options> <fs_mgr_flags>
# More comments.....

/dev/block/by-name/system     /system     ext4    ro,barrier=1    wait
/dev/block/by-name/vendor     /vendor     ext4    ro              wait,verify=/dev/metadata
/dev/block/by-name/cache      /cache      ext4    noatime,errors=panic      wait,check
/dev/block/by-name/modem      /firmware   vfat    ro,uid=1000,gid=1000,     wait
/dev/block/by-name/boot       /boot       emmc    defaults        defaults
/dev/block/by-name/recovery   /recovery   emmc    defaults        defaults
/dev/block/by-name/misc       /misc       emmc    defaults
/dev/block/by-name/modem      /modem      emmc    defaults        defaults)";

    raw_system_string_ = "system.img" + string(4086, '\0');  // raw image is 4096 bytes in total
    sparse_system_string_ = string(SPARSE_SYSTEM_HEADER, std::end(SPARSE_SYSTEM_HEADER)) +
                            string(4136 - sizeof(SPARSE_SYSTEM_HEADER), '\0');
  }

  string build_prop_string_;
  string fstab_content_;
  string raw_system_string_;
  string sparse_system_string_;
};

TEST_F(UpdateSimulatorTest, TargetFile_ExtractImage) {
  TemporaryFile zip_file;
  AddZipEntries(zip_file.release(), { { "META/misc_info.txt", "extfs_sparse_flag=-s" },
                                      { "IMAGES/system.img", sparse_system_string_ } });
  TargetFile target_file(zip_file.path, false);
  ASSERT_TRUE(target_file.Open());

  TemporaryDir temp_dir;
  TemporaryFile raw_image;
  ASSERT_TRUE(target_file.ExtractImage(
      "IMAGES/system.img", FstabInfo("/dev/system", "system", "ext4"), temp_dir.path, &raw_image));

  // Check the raw image has expected contents.
  string content;
  ASSERT_TRUE(android::base::ReadFileToString(raw_image.path, &content));
  string expected_content = "system.img" + string(4086, '\0');
  ASSERT_EQ(expected_content, content);
}

TEST_F(UpdateSimulatorTest, TargetFile_ParseFstabInfo) {
  TemporaryFile zip_file;
  AddZipEntries(zip_file.release(),
                { { "META/misc_info.txt", "" },
                  { "RECOVERY/RAMDISK/system/etc/recovery.fstab", fstab_content_ } });
  TargetFile target_file(zip_file.path, false);
  ASSERT_TRUE(target_file.Open());

  std::vector<FstabInfo> fstab_info;
  EXPECT_TRUE(target_file.ParseFstabInfo(&fstab_info));

  std::vector<std::vector<string>> transformed;
  std::transform(fstab_info.begin(), fstab_info.end(), std::back_inserter(transformed),
                 [](const FstabInfo& info) {
                   return std::vector<string>{ info.blockdev_name, info.mount_point, info.fs_type };
                 });

  std::vector<std::vector<string>> expected = {
    { "/dev/block/by-name/system", "/system", "ext4" },
    { "/dev/block/by-name/vendor", "/vendor", "ext4" },
    { "/dev/block/by-name/cache", "/cache", "ext4" },
    { "/dev/block/by-name/boot", "/boot", "emmc" },
    { "/dev/block/by-name/recovery", "/recovery", "emmc" },
    { "/dev/block/by-name/misc", "/misc", "emmc" },
    { "/dev/block/by-name/modem", "/modem", "emmc" },
  };
  EXPECT_EQ(expected, transformed);
}

TEST_F(UpdateSimulatorTest, BuildInfo_ParseTargetFile) {
  std::map<string, string> entries = {
    { "META/misc_info.txt", "" },
    { "SYSTEM/build.prop", build_prop_string_ },
    { "RECOVERY/RAMDISK/system/etc/recovery.fstab", fstab_content_ },
    { "IMAGES/recovery.img", "" },
    { "IMAGES/boot.img", "" },
    { "IMAGES/misc.img", "" },
    { "IMAGES/system.map", "" },
    { "IMAGES/system.img", sparse_system_string_ },
  };

  TemporaryFile zip_file;
  AddZipEntries(zip_file.release(), entries);

  TemporaryDir temp_dir;
  BuildInfo build_info(temp_dir.path);
  ASSERT_TRUE(build_info.ParseTargetFile(zip_file.path, false));

  std::map<string, string> expected_result = {
    { "ro.build.id", "OPR1.170510.001" },
    { "ro.build.display.id", "OPR1.170510.001 dev-keys" },
    { "ro.build.version.incremental", "3993052" },
    { "ro.build.version.release", "O" },
    { "ro.build.date", "Wed May 10 11:10:29 UTC 2017" },
    { "ro.build.date.utc", "1494414629" },
    { "ro.build.type", "user" },
    { "ro.build.tags", "dev-keys" },
    { "ro.build.flavor", "angler-user" },
    { "ro.product.brand", "google" },
    { "ro.product.name", "angler" },
    { "ro.product.device", "angler" },
  };

  for (const auto& [key, value] : expected_result) {
    ASSERT_EQ(value, build_info.GetProperty(key, ""));
  }

  // Check that the temp files for each block device are created successfully.
  for (auto name : { "/dev/block/by-name/system", "/dev/block/by-name/recovery",
                     "/dev/block/by-name/boot", "/dev/block/by-name/misc" }) {
    ASSERT_EQ(0, access(build_info.FindBlockDeviceName(name).c_str(), R_OK));
  }
}

TEST_F(UpdateSimulatorTest, RunUpdateSmoke) {
  string recovery_img_string = "recovery.img";
  string boot_img_string = "boot.img";

  std::map<string, string> src_entries{
    { "META/misc_info.txt", "extfs_sparse_flag=-s" },
    { "RECOVERY/RAMDISK/etc/recovery.fstab", fstab_content_ },
    { "SYSTEM/build.prop", build_prop_string_ },
    { "IMAGES/recovery.img", "" },
    { "IMAGES/boot.img", boot_img_string },
    { "IMAGES/system.img", sparse_system_string_ },
  };

  // Construct the source target-files.
  TemporaryFile src_tf;
  AddZipEntries(src_tf.release(), src_entries);

  string recovery_from_boot;
  CreateBsdiffPatch(boot_img_string, recovery_img_string, &recovery_from_boot);

  // Set up the apply patch commands to patch the recovery image.
  string recovery_sha1 = CalculateSha1(recovery_img_string);
  string boot_sha1 = CalculateSha1(boot_img_string);
  string apply_patch_source_string = android::base::StringPrintf(
      "EMMC:/dev/block/by-name/boot:%zu:%s", boot_img_string.size(), boot_sha1.c_str());
  string apply_patch_target_string = android::base::StringPrintf(
      "EMMC:/dev/block/by-name/recovery:%zu:%s", recovery_img_string.size(), recovery_sha1.c_str());
  string check_command = android::base::StringPrintf(
      R"(patch_partition_check("%s", "%s") || abort("check failed");)",
      apply_patch_target_string.c_str(), apply_patch_source_string.c_str());
  string patch_command = android::base::StringPrintf(
      R"(patch_partition("%s", "%s", package_extract_file("patch.p")) || abort("patch failed");)",
      apply_patch_target_string.c_str(), apply_patch_source_string.c_str());

  // Add the commands to update the system image. Test common commands:
  // * getprop
  // * ui_print
  // * patch_partition
  // * package_extract_file (single argument)
  // * block_image_verify, block_image_update
  string tgt_system_string = string(4096, 'a');
  string system_patch;
  CreateBsdiffPatch(raw_system_string_, tgt_system_string, &system_patch);

  string tgt_system_hash = CalculateSha1(tgt_system_string);
  string src_system_hash = CalculateSha1(raw_system_string_);

  std::vector<std::string> transfer_list = {
    "4",
    "1",
    "0",
    "0",
    android::base::StringPrintf("bsdiff 0 %zu %s %s 2,0,1 1 2,0,1", system_patch.size(),
                                src_system_hash.c_str(), tgt_system_hash.c_str()),
  };

  // Construct the updater_script.
  std::vector<string> updater_commands = {
    R"(getprop("ro.product.device") == "angler" || abort("This package is for \"angler\"");)",
    R"(ui_print("Source: angler/OPR1.170510.001");)",
    check_command,
    patch_command,
    R"(block_image_verify("/dev/block/by-name/system", )"
    R"(package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") || )"
    R"(abort("Failed to verify system.");)",
    R"(block_image_update("/dev/block/by-name/system", )"
    R"(package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") || )"
    R"(abort("Failed to verify system.");)",
  };
  string updater_script = android::base::Join(updater_commands, '\n');

  // Construct the ota update package.
  std::map<string, string> ota_entries{
    { "system.new.dat", "" },
    { "system.patch.dat", system_patch },
    { "system.transfer.list", android::base::Join(transfer_list, '\n') },
    { "META-INF/com/google/android/updater-script", updater_script },
    { "patch.p", recovery_from_boot },
  };

  TemporaryFile ota_package;
  AddZipEntries(ota_package.release(), ota_entries);

  RunSimulation(src_tf.path, ota_package.path, true);
}

TEST_F(UpdateSimulatorTest, RunUpdateUnrecognizedFunction) {
  std::map<string, string> src_entries{
    { "META/misc_info.txt", "extfs_sparse_flag=-s" },
    { "IMAGES/system.img", sparse_system_string_ },
    { "RECOVERY/RAMDISK/etc/recovery.fstab", fstab_content_ },
    { "SYSTEM/build.prop", build_prop_string_ },
  };

  TemporaryFile src_tf;
  AddZipEntries(src_tf.release(), src_entries);

  std::map<string, string> ota_entries{
    { "system.new.dat", "" },
    { "system.patch.dat", "" },
    { "system.transfer.list", "" },
    { "META-INF/com/google/android/updater-script", R"(bad_function("");)" },
  };

  TemporaryFile ota_package;
  AddZipEntries(ota_package.release(), ota_entries);

  RunSimulation(src_tf.path, ota_package.path, false);
}

TEST_F(UpdateSimulatorTest, RunUpdateApplyPatchFailed) {
  string recovery_img_string = "recovery.img";
  string boot_img_string = "boot.img";

  std::map<string, string> src_entries{
    { "META/misc_info.txt", "extfs_sparse_flag=-s" },
    { "IMAGES/recovery.img", "" },
    { "IMAGES/boot.img", boot_img_string },
    { "IMAGES/system.img", sparse_system_string_ },
    { "RECOVERY/RAMDISK/etc/recovery.fstab", fstab_content_ },
    { "SYSTEM/build.prop", build_prop_string_ },
  };

  TemporaryFile src_tf;
  AddZipEntries(src_tf.release(), src_entries);

  string recovery_sha1 = CalculateSha1(recovery_img_string);
  string boot_sha1 = CalculateSha1(boot_img_string);
  string apply_patch_source_string = android::base::StringPrintf(
      "EMMC:/dev/block/by-name/boot:%zu:%s", boot_img_string.size(), boot_sha1.c_str());
  string apply_patch_target_string = android::base::StringPrintf(
      "EMMC:/dev/block/by-name/recovery:%zu:%s", recovery_img_string.size(), recovery_sha1.c_str());
  string check_command = android::base::StringPrintf(
      R"(patch_partition_check("%s", "%s") || abort("check failed");)",
      apply_patch_target_string.c_str(), apply_patch_source_string.c_str());
  string patch_command = android::base::StringPrintf(
      R"(patch_partition("%s", "%s", package_extract_file("patch.p")) || abort("failed");)",
      apply_patch_target_string.c_str(), apply_patch_source_string.c_str());

  // Give an invalid recovery patch and expect the apply patch to fail.
  // TODO(xunchang) check the cause code.
  std::vector<string> updater_commands = {
    R"(ui_print("Source: angler/OPR1.170510.001");)",
    check_command,
    patch_command,
  };

  string updater_script = android::base::Join(updater_commands, '\n');
  std::map<string, string> ota_entries{
    { "system.new.dat", "" },
    { "system.patch.dat", "" },
    { "system.transfer.list", "" },
    { "META-INF/com/google/android/updater-script", updater_script },
    { "patch.p", "random string" },
  };

  TemporaryFile ota_package;
  AddZipEntries(ota_package.release(), ota_entries);

  RunSimulation(src_tf.path, ota_package.path, false);
}
