/*
 * 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, false);
  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, false);
  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);
}
