/*
 * Copyright (C) 2016 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 <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

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

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <bootloader_message/bootloader_message.h>
#include <brotli/encode.h>
#include <bsdiff/bsdiff.h>
#include <gtest/gtest.h>
#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_writer.h>

#include "common/test_constants.h"
#include "edify/expr.h"
#include "otautil/error_code.h"
#include "otautil/paths.h"
#include "otautil/print_sha1.h"
#include "otautil/sysutil.h"
#include "private/commands.h"
#include "updater/blockimg.h"
#include "updater/install.h"
#include "updater/updater.h"

using PackageEntries = std::unordered_map<std::string, std::string>;

static constexpr size_t kTransferListHeaderLines = 4;

struct selabel_handle* sehandle = nullptr;

static void expect(const char* expected, const char* expr_str, CauseCode cause_code,
                   UpdaterInfo* info = nullptr) {
  std::unique_ptr<Expr> e;
  int error_count = 0;
  ASSERT_EQ(0, parse_string(expr_str, &e, &error_count));
  ASSERT_EQ(0, error_count);

  State state(expr_str, info);

  std::string result;
  bool status = Evaluate(&state, e, &result);

  if (expected == nullptr) {
    ASSERT_FALSE(status);
  } else {
    ASSERT_TRUE(status) << "Evaluate() finished with error message: " << state.errmsg;
    ASSERT_STREQ(expected, result.c_str());
  }

  // Error code is set in updater/updater.cpp only, by parsing State.errmsg.
  ASSERT_EQ(kNoError, state.error_code);

  // Cause code should always be available.
  ASSERT_EQ(cause_code, state.cause_code);
}

static void BuildUpdatePackage(const PackageEntries& entries, int fd) {
  FILE* zip_file_ptr = fdopen(fd, "wb");
  ZipWriter zip_writer(zip_file_ptr);

  for (const auto& entry : entries) {
    // All the entries are written as STORED.
    ASSERT_EQ(0, zip_writer.StartEntry(entry.first.c_str(), 0));
    if (!entry.second.empty()) {
      ASSERT_EQ(0, zip_writer.WriteBytes(entry.second.data(), entry.second.size()));
    }
    ASSERT_EQ(0, zip_writer.FinishEntry());
  }

  ASSERT_EQ(0, zip_writer.Finish());
  ASSERT_EQ(0, fclose(zip_file_ptr));
}

static void RunBlockImageUpdate(bool is_verify, const PackageEntries& entries,
                                const std::string& image_file, const std::string& result,
                                CauseCode cause_code = kNoCause) {
  CHECK(entries.find("transfer_list") != entries.end());

  // Build the update package.
  TemporaryFile zip_file;
  BuildUpdatePackage(entries, zip_file.release());

  MemMapping map;
  ASSERT_TRUE(map.MapFile(zip_file.path));
  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle));

  // Set up the handler, command_pipe, patch offset & length.
  UpdaterInfo updater_info;
  updater_info.package_zip = handle;
  TemporaryFile temp_pipe;
  updater_info.cmd_pipe = fdopen(temp_pipe.release(), "wbe");
  updater_info.package_zip_addr = map.addr;
  updater_info.package_zip_len = map.length;

  std::string new_data = entries.find("new_data.br") != entries.end() ? "new_data.br" : "new_data";
  std::string script = is_verify ? "block_image_verify" : "block_image_update";
  script += R"((")" + image_file + R"(", package_extract_file("transfer_list"), ")" + new_data +
            R"(", "patch_data"))";
  expect(result.c_str(), script.c_str(), cause_code, &updater_info);

  ASSERT_EQ(0, fclose(updater_info.cmd_pipe));
  CloseArchive(handle);
}

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

static Value* BlobToString(const char* name, State* state,
                           const std::vector<std::unique_ptr<Expr>>& argv) {
  if (argv.size() != 1) {
    return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
  }

  std::vector<std::unique_ptr<Value>> args;
  if (!ReadValueArgs(state, argv, &args)) {
    return nullptr;
  }

  if (args[0]->type != Value::Type::BLOB) {
    return ErrorAbort(state, kArgsParsingFailure, "%s() expects a BLOB argument", name);
  }

  args[0]->type = Value::Type::STRING;
  return args[0].release();
}

class UpdaterTest : public ::testing::Test {
 protected:
  void SetUp() override {
    RegisterBuiltins();
    RegisterInstallFunctions();
    RegisterBlockImageFunctions();

    RegisterFunction("blob_to_string", BlobToString);

    // Each test is run in a separate process (isolated mode). Shared temporary files won't cause
    // conflicts.
    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);

    // Enable a special command "abort" to simulate interruption.
    Command::abort_allowed_ = true;

    last_command_file_ = temp_last_command_.path;
    image_file_ = image_temp_file_.path;
  }

  void TearDown() override {
    // Clean up the last_command_file if any.
    ASSERT_TRUE(android::base::RemoveFileIfExists(last_command_file_));

    // Clear partition updated marker if any.
    std::string updated_marker{ temp_stash_base_.path };
    updated_marker += "/" + get_sha1(image_temp_file_.path) + ".UPDATED";
    ASSERT_TRUE(android::base::RemoveFileIfExists(updated_marker));
  }

  TemporaryFile temp_saved_source_;
  TemporaryDir temp_stash_base_;
  std::string last_command_file_;
  std::string image_file_;

 private:
  TemporaryFile temp_last_command_;
  TemporaryFile image_temp_file_;
};

TEST_F(UpdaterTest, getprop) {
    expect(android::base::GetProperty("ro.product.device", "").c_str(),
           "getprop(\"ro.product.device\")",
           kNoCause);

    expect(android::base::GetProperty("ro.build.fingerprint", "").c_str(),
           "getprop(\"ro.build.fingerprint\")",
           kNoCause);

    // getprop() accepts only one parameter.
    expect(nullptr, "getprop()", kArgsParsingFailure);
    expect(nullptr, "getprop(\"arg1\", \"arg2\")", kArgsParsingFailure);
}

TEST_F(UpdaterTest, apply_patch_check) {
  // Zero-argument is not valid.
  expect(nullptr, "apply_patch_check()", kArgsParsingFailure);

  // File not found.
  expect("", "apply_patch_check(\"/doesntexist\")", kNoCause);

  std::string src_file = from_testdata_base("old.file");
  std::string src_content;
  ASSERT_TRUE(android::base::ReadFileToString(src_file, &src_content));
  size_t src_size = src_content.size();
  std::string src_hash = get_sha1(src_content);

  // One-argument with EMMC:file:size:sha1 should pass the check.
  std::string filename = android::base::Join(
      std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size), src_hash }, ":");
  std::string cmd = "apply_patch_check(\"" + filename + "\")";
  expect("t", cmd.c_str(), kNoCause);

  // EMMC:file:(size-1):sha1:(size+1):sha1 should fail the check.
  std::string filename_bad = android::base::Join(
      std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1), src_hash,
                                std::to_string(src_size + 1), src_hash },
      ":");
  cmd = "apply_patch_check(\"" + filename_bad + "\")";
  expect("", cmd.c_str(), kNoCause);

  // EMMC:file:(size-1):sha1:size:sha1:(size+1):sha1 should pass the check.
  filename_bad =
      android::base::Join(std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1),
                                                    src_hash, std::to_string(src_size), src_hash,
                                                    std::to_string(src_size + 1), src_hash },
                          ":");
  cmd = "apply_patch_check(\"" + filename_bad + "\")";
  expect("t", cmd.c_str(), kNoCause);

  // Multiple arguments.
  // As long as it successfully loads the partition specified in filename, it won't check against
  // any given SHAs.
  cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"wrong_sha2\")";
  expect("t", cmd.c_str(), kNoCause);

  cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"" + src_hash +
        "\", \"wrong_sha2\")";
  expect("t", cmd.c_str(), kNoCause);

  cmd = "apply_patch_check(\"" + filename_bad + "\", \"wrong_sha1\", \"" + src_hash +
        "\", \"wrong_sha2\")";
  expect("t", cmd.c_str(), kNoCause);
}

TEST_F(UpdaterTest, file_getprop) {
    // file_getprop() expects two arguments.
    expect(nullptr, "file_getprop()", kArgsParsingFailure);
    expect(nullptr, "file_getprop(\"arg1\")", kArgsParsingFailure);
    expect(nullptr, "file_getprop(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

    // File doesn't exist.
    expect(nullptr, "file_getprop(\"/doesntexist\", \"key1\")", kFileGetPropFailure);

    // Reject too large files (current limit = 65536).
    TemporaryFile temp_file1;
    std::string buffer(65540, '\0');
    ASSERT_TRUE(android::base::WriteStringToFile(buffer, temp_file1.path));

    // Read some keys.
    TemporaryFile temp_file2;
    std::string content("ro.product.name=tardis\n"
                        "# comment\n\n\n"
                        "ro.product.model\n"
                        "ro.product.board =  magic \n");
    ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file2.path));

    std::string script1("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.name\")");
    expect("tardis", script1.c_str(), kNoCause);

    std::string script2("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.board\")");
    expect("magic", script2.c_str(), kNoCause);

    // No match.
    std::string script3("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.wrong\")");
    expect("", script3.c_str(), kNoCause);

    std::string script4("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.name=\")");
    expect("", script4.c_str(), kNoCause);

    std::string script5("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.nam\")");
    expect("", script5.c_str(), kNoCause);

    std::string script6("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.model\")");
    expect("", script6.c_str(), kNoCause);
}

// TODO: Test extracting to block device.
TEST_F(UpdaterTest, package_extract_file) {
  // package_extract_file expects 1 or 2 arguments.
  expect(nullptr, "package_extract_file()", kArgsParsingFailure);
  expect(nullptr, "package_extract_file(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

  std::string zip_path = from_testdata_base("ziptest_valid.zip");
  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle));

  // Need to set up the ziphandle.
  UpdaterInfo updater_info;
  updater_info.package_zip = handle;

  // Two-argument version.
  TemporaryFile temp_file1;
  std::string script("package_extract_file(\"a.txt\", \"" + std::string(temp_file1.path) + "\")");
  expect("t", script.c_str(), kNoCause, &updater_info);

  // Verify the extracted entry.
  std::string data;
  ASSERT_TRUE(android::base::ReadFileToString(temp_file1.path, &data));
  ASSERT_EQ(kATxtContents, data);

  // Now extract another entry to the same location, which should overwrite.
  script = "package_extract_file(\"b.txt\", \"" + std::string(temp_file1.path) + "\")";
  expect("t", script.c_str(), kNoCause, &updater_info);

  ASSERT_TRUE(android::base::ReadFileToString(temp_file1.path, &data));
  ASSERT_EQ(kBTxtContents, data);

  // Missing zip entry. The two-argument version doesn't abort.
  script = "package_extract_file(\"doesntexist\", \"" + std::string(temp_file1.path) + "\")";
  expect("", script.c_str(), kNoCause, &updater_info);

  // Extract to /dev/full should fail.
  script = "package_extract_file(\"a.txt\", \"/dev/full\")";
  expect("", script.c_str(), kNoCause, &updater_info);

  // One-argument version. package_extract_file() gives a VAL_BLOB, which needs to be converted to
  // VAL_STRING for equality test.
  script = "blob_to_string(package_extract_file(\"a.txt\")) == \"" + kATxtContents + "\"";
  expect("t", script.c_str(), kNoCause, &updater_info);

  script = "blob_to_string(package_extract_file(\"b.txt\")) == \"" + kBTxtContents + "\"";
  expect("t", script.c_str(), kNoCause, &updater_info);

  // Missing entry. The one-argument version aborts the evaluation.
  script = "package_extract_file(\"doesntexist\")";
  expect(nullptr, script.c_str(), kPackageExtractFileFailure, &updater_info);

  CloseArchive(handle);
}

TEST_F(UpdaterTest, write_value) {
  // write_value() expects two arguments.
  expect(nullptr, "write_value()", kArgsParsingFailure);
  expect(nullptr, "write_value(\"arg1\")", kArgsParsingFailure);
  expect(nullptr, "write_value(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

  // filename cannot be empty.
  expect(nullptr, "write_value(\"value\", \"\")", kArgsParsingFailure);

  // Write some value to file.
  TemporaryFile temp_file;
  std::string value = "magicvalue";
  std::string script("write_value(\"" + value + "\", \"" + std::string(temp_file.path) + "\")");
  expect("t", script.c_str(), kNoCause);

  // Verify the content.
  std::string content;
  ASSERT_TRUE(android::base::ReadFileToString(temp_file.path, &content));
  ASSERT_EQ(value, content);

  // Allow writing empty string.
  script = "write_value(\"\", \"" + std::string(temp_file.path) + "\")";
  expect("t", script.c_str(), kNoCause);

  // Verify the content.
  ASSERT_TRUE(android::base::ReadFileToString(temp_file.path, &content));
  ASSERT_EQ("", content);

  // It should fail gracefully when write fails.
  script = "write_value(\"value\", \"/proc/0/file1\")";
  expect("", script.c_str(), kNoCause);
}

TEST_F(UpdaterTest, get_stage) {
  // get_stage() expects one argument.
  expect(nullptr, "get_stage()", kArgsParsingFailure);
  expect(nullptr, "get_stage(\"arg1\", \"arg2\")", kArgsParsingFailure);
  expect(nullptr, "get_stage(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

  // Set up a local file as BCB.
  TemporaryFile tf;
  std::string temp_file(tf.path);
  bootloader_message boot;
  strlcpy(boot.stage, "2/3", sizeof(boot.stage));
  std::string err;
  ASSERT_TRUE(write_bootloader_message_to(boot, temp_file, &err));

  // Can read the stage value.
  std::string script("get_stage(\"" + temp_file + "\")");
  expect("2/3", script.c_str(), kNoCause);

  // Bad BCB path.
  script = "get_stage(\"doesntexist\")";
  expect("", script.c_str(), kNoCause);
}

TEST_F(UpdaterTest, set_stage) {
  // set_stage() expects two arguments.
  expect(nullptr, "set_stage()", kArgsParsingFailure);
  expect(nullptr, "set_stage(\"arg1\")", kArgsParsingFailure);
  expect(nullptr, "set_stage(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

  // Set up a local file as BCB.
  TemporaryFile tf;
  std::string temp_file(tf.path);
  bootloader_message boot;
  strlcpy(boot.command, "command", sizeof(boot.command));
  strlcpy(boot.stage, "2/3", sizeof(boot.stage));
  std::string err;
  ASSERT_TRUE(write_bootloader_message_to(boot, temp_file, &err));

  // Write with set_stage().
  std::string script("set_stage(\"" + temp_file + "\", \"1/3\")");
  expect(tf.path, script.c_str(), kNoCause);

  // Verify.
  bootloader_message boot_verify;
  ASSERT_TRUE(read_bootloader_message_from(&boot_verify, temp_file, &err));

  // Stage should be updated, with command part untouched.
  ASSERT_STREQ("1/3", boot_verify.stage);
  ASSERT_STREQ(boot.command, boot_verify.command);

  // Bad BCB path.
  script = "set_stage(\"doesntexist\", \"1/3\")";
  expect("", script.c_str(), kNoCause);

  script = "set_stage(\"/dev/full\", \"1/3\")";
  expect("", script.c_str(), kNoCause);
}

TEST_F(UpdaterTest, set_progress) {
  // set_progress() expects one argument.
  expect(nullptr, "set_progress()", kArgsParsingFailure);
  expect(nullptr, "set_progress(\"arg1\", \"arg2\")", kArgsParsingFailure);

  // Invalid progress argument.
  expect(nullptr, "set_progress(\"arg1\")", kArgsParsingFailure);
  expect(nullptr, "set_progress(\"3x+5\")", kArgsParsingFailure);
  expect(nullptr, "set_progress(\".3.5\")", kArgsParsingFailure);

  TemporaryFile tf;
  UpdaterInfo updater_info;
  updater_info.cmd_pipe = fdopen(tf.release(), "w");
  expect(".52", "set_progress(\".52\")", kNoCause, &updater_info);
  fflush(updater_info.cmd_pipe);

  std::string cmd;
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &cmd));
  ASSERT_EQ(android::base::StringPrintf("set_progress %f\n", .52), cmd);
  // recovery-updater protocol expects 2 tokens ("set_progress <frac>").
  ASSERT_EQ(2U, android::base::Split(cmd, " ").size());
  ASSERT_EQ(0, fclose(updater_info.cmd_pipe));
}

TEST_F(UpdaterTest, show_progress) {
  // show_progress() expects two arguments.
  expect(nullptr, "show_progress()", kArgsParsingFailure);
  expect(nullptr, "show_progress(\"arg1\")", kArgsParsingFailure);
  expect(nullptr, "show_progress(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);

  // Invalid progress arguments.
  expect(nullptr, "show_progress(\"arg1\", \"arg2\")", kArgsParsingFailure);
  expect(nullptr, "show_progress(\"3x+5\", \"10\")", kArgsParsingFailure);
  expect(nullptr, "show_progress(\".3\", \"5a\")", kArgsParsingFailure);

  TemporaryFile tf;
  UpdaterInfo updater_info;
  updater_info.cmd_pipe = fdopen(tf.release(), "w");
  expect(".52", "show_progress(\".52\", \"10\")", kNoCause, &updater_info);
  fflush(updater_info.cmd_pipe);

  std::string cmd;
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &cmd));
  ASSERT_EQ(android::base::StringPrintf("progress %f %d\n", .52, 10), cmd);
  // recovery-updater protocol expects 3 tokens ("progress <frac> <secs>").
  ASSERT_EQ(3U, android::base::Split(cmd, " ").size());
  ASSERT_EQ(0, fclose(updater_info.cmd_pipe));
}

TEST_F(UpdaterTest, block_image_update_parsing_error) {
  std::vector<std::string> transfer_list{
    // clang-format off
    "4",
    "2",
    "0",
    // clang-format on
  };

  PackageEntries entries{
    { "new_data", "" },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  RunBlockImageUpdate(false, entries, image_file_, "", kArgsParsingFailure);
}

TEST_F(UpdaterTest, block_image_update_patch_data) {
  std::string src_content = std::string(4096, 'a') + std::string(4096, 'c');
  std::string tgt_content = std::string(4096, 'b') + std::string(4096, 'd');

  // Generate the patch data.
  TemporaryFile patch_file;
  ASSERT_EQ(0,
            bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(src_content.data()), src_content.size(),
                           reinterpret_cast<const uint8_t*>(tgt_content.data()), tgt_content.size(),
                           patch_file.path, nullptr));
  std::string patch_content;
  ASSERT_TRUE(android::base::ReadFileToString(patch_file.path, &patch_content));

  // Create the transfer list that contains a bsdiff.
  std::string src_hash = get_sha1(src_content);
  std::string tgt_hash = get_sha1(tgt_content);
  std::vector<std::string> transfer_list{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + src_hash + " 2,0,2",
    android::base::StringPrintf("bsdiff 0 %zu %s %s 2,0,2 2 - %s:2,0,2", patch_content.size(),
                                src_hash.c_str(), tgt_hash.c_str(), src_hash.c_str()),
    "free " + src_hash,
    // clang-format on
  };

  PackageEntries entries{
    { "new_data", "" },
    { "patch_data", patch_content },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  ASSERT_TRUE(android::base::WriteStringToFile(src_content, image_file_));

  RunBlockImageUpdate(false, entries, image_file_, "t");

  // The update_file should be patched correctly.
  std::string updated_content;
  ASSERT_TRUE(android::base::ReadFileToString(image_file_, &updated_content));
  ASSERT_EQ(tgt_content, updated_content);
}

TEST_F(UpdaterTest, block_image_update_fail) {
  std::string src_content(4096 * 2, 'e');
  std::string src_hash = get_sha1(src_content);
  // Stash and free some blocks, then fail the update intentionally.
  std::vector<std::string> transfer_list{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + src_hash + " 2,0,2",
    "free " + src_hash,
    "abort",
    // clang-format on
  };

  // Add a new data of 10 bytes to test the deadlock.
  PackageEntries entries{
    { "new_data", std::string(10, 0) },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  ASSERT_TRUE(android::base::WriteStringToFile(src_content, image_file_));

  RunBlockImageUpdate(false, entries, image_file_, "");

  // Updater generates the stash name based on the input file name.
  std::string name_digest = get_sha1(image_file_);
  std::string stash_base = std::string(temp_stash_base_.path) + "/" + name_digest;
  ASSERT_EQ(0, access(stash_base.c_str(), F_OK));
  // Expect the stashed blocks to be freed.
  ASSERT_EQ(-1, access((stash_base + src_hash).c_str(), F_OK));
  ASSERT_EQ(0, rmdir(stash_base.c_str()));
}

TEST_F(UpdaterTest, new_data_over_write) {
  std::vector<std::string> transfer_list{
    // clang-format off
    "4",
    "1",
    "0",
    "0",
    "new 2,0,1",
    // clang-format on
  };

  // Write 4096 + 100 bytes of new data.
  PackageEntries entries{
    { "new_data", std::string(4196, 0) },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  RunBlockImageUpdate(false, entries, image_file_, "t");
}

TEST_F(UpdaterTest, new_data_short_write) {
  std::vector<std::string> transfer_list{
    // clang-format off
    "4",
    "1",
    "0",
    "0",
    "new 2,0,1",
    // clang-format on
  };

  PackageEntries entries{
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  // Updater should report the failure gracefully rather than stuck in deadlock.
  entries["new_data"] = "";
  RunBlockImageUpdate(false, entries, image_file_, "");

  entries["new_data"] = std::string(10, 'a');
  RunBlockImageUpdate(false, entries, image_file_, "");

  // Expect to write 1 block of new data successfully.
  entries["new_data"] = std::string(4096, 'a');
  RunBlockImageUpdate(false, entries, image_file_, "t");
}

TEST_F(UpdaterTest, brotli_new_data) {
  auto generator = []() { return rand() % 128; };
  // Generate 100 blocks of random data.
  std::string brotli_new_data;
  brotli_new_data.reserve(4096 * 100);
  generate_n(back_inserter(brotli_new_data), 4096 * 100, generator);

  size_t encoded_size = BrotliEncoderMaxCompressedSize(brotli_new_data.size());
  std::string encoded_data(encoded_size, 0);
  ASSERT_TRUE(BrotliEncoderCompress(
      BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE, brotli_new_data.size(),
      reinterpret_cast<const uint8_t*>(brotli_new_data.data()), &encoded_size,
      reinterpret_cast<uint8_t*>(const_cast<char*>(encoded_data.data()))));
  encoded_data.resize(encoded_size);

  // Write a few small chunks of new data, then a large chunk, and finally a few small chunks.
  // This helps us to catch potential short writes.
  std::vector<std::string> transfer_list = {
    "4",
    "100",
    "0",
    "0",
    "new 2,0,1",
    "new 2,1,2",
    "new 4,2,50,50,97",
    "new 2,97,98",
    "new 2,98,99",
    "new 2,99,100",
  };

  PackageEntries entries{
    { "new_data.br", std::move(encoded_data) },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list, '\n') },
  };

  RunBlockImageUpdate(false, entries, image_file_, "t");

  std::string updated_content;
  ASSERT_TRUE(android::base::ReadFileToString(image_file_, &updated_content));
  ASSERT_EQ(brotli_new_data, updated_content);
}

TEST_F(UpdaterTest, last_command_update) {
  std::string block1(4096, '1');
  std::string block2(4096, '2');
  std::string block3(4096, '3');
  std::string block1_hash = get_sha1(block1);
  std::string block2_hash = get_sha1(block2);
  std::string block3_hash = get_sha1(block3);

  // Compose the transfer list to fail the first update.
  std::vector<std::string> transfer_list_fail{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + block1_hash + " 2,0,1",
    "move " + block1_hash + " 2,1,2 1 2,0,1",
    "stash " + block3_hash + " 2,2,3",
    "abort",
    // clang-format on
  };

  // Mimic a resumed update with the same transfer commands.
  std::vector<std::string> transfer_list_continue{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + block1_hash + " 2,0,1",
    "move " + block1_hash + " 2,1,2 1 2,0,1",
    "stash " + block3_hash + " 2,2,3",
    "move " + block1_hash + " 2,2,3 1 2,0,1",
    // clang-format on
  };

  ASSERT_TRUE(android::base::WriteStringToFile(block1 + block2 + block3, image_file_));

  PackageEntries entries{
    { "new_data", "" },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list_fail, '\n') },
  };

  // "2\nstash " + block3_hash + " 2,2,3"
  std::string last_command_content = "2\n" + transfer_list_fail[kTransferListHeaderLines + 2];

  RunBlockImageUpdate(false, entries, image_file_, "");

  // Expect last_command to contain the last stash command.
  std::string last_command_actual;
  ASSERT_TRUE(android::base::ReadFileToString(last_command_file_, &last_command_actual));
  EXPECT_EQ(last_command_content, last_command_actual);

  std::string updated_contents;
  ASSERT_TRUE(android::base::ReadFileToString(image_file_, &updated_contents));
  ASSERT_EQ(block1 + block1 + block3, updated_contents);

  // "Resume" the update. Expect the first 'move' to be skipped but the second 'move' to be
  // executed. Note that we intentionally reset the image file.
  entries["transfer_list"] = android::base::Join(transfer_list_continue, '\n');
  ASSERT_TRUE(android::base::WriteStringToFile(block1 + block2 + block3, image_file_));
  RunBlockImageUpdate(false, entries, image_file_, "t");

  ASSERT_TRUE(android::base::ReadFileToString(image_file_, &updated_contents));
  ASSERT_EQ(block1 + block2 + block1, updated_contents);
}

TEST_F(UpdaterTest, last_command_update_unresumable) {
  std::string block1(4096, '1');
  std::string block2(4096, '2');
  std::string block1_hash = get_sha1(block1);
  std::string block2_hash = get_sha1(block2);

  // Construct an unresumable update with source blocks mismatch.
  std::vector<std::string> transfer_list_unresumable{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + block1_hash + " 2,0,1",
    "move " + block2_hash + " 2,1,2 1 2,0,1",
    // clang-format on
  };

  PackageEntries entries{
    { "new_data", "" },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list_unresumable, '\n') },
  };

  ASSERT_TRUE(android::base::WriteStringToFile(block1 + block1, image_file_));

  std::string last_command_content = "0\n" + transfer_list_unresumable[kTransferListHeaderLines];
  ASSERT_TRUE(android::base::WriteStringToFile(last_command_content, last_command_file_));

  RunBlockImageUpdate(false, entries, image_file_, "");

  // The last_command_file will be deleted if the update encounters an unresumable failure later.
  ASSERT_EQ(-1, access(last_command_file_.c_str(), R_OK));
}

TEST_F(UpdaterTest, last_command_verify) {
  std::string block1(4096, '1');
  std::string block2(4096, '2');
  std::string block3(4096, '3');
  std::string block1_hash = get_sha1(block1);
  std::string block2_hash = get_sha1(block2);
  std::string block3_hash = get_sha1(block3);

  std::vector<std::string> transfer_list_verify{
    // clang-format off
    "4",
    "2",
    "0",
    "2",
    "stash " + block1_hash + " 2,0,1",
    "move " + block1_hash + " 2,0,1 1 2,0,1",
    "move " + block1_hash + " 2,1,2 1 2,0,1",
    "stash " + block3_hash + " 2,2,3",
    // clang-format on
  };

  PackageEntries entries{
    { "new_data", "" },
    { "patch_data", "" },
    { "transfer_list", android::base::Join(transfer_list_verify, '\n') },
  };

  ASSERT_TRUE(android::base::WriteStringToFile(block1 + block1 + block3, image_file_));

  // Last command: "move " + block1_hash + " 2,1,2 1 2,0,1"
  std::string last_command_content = "2\n" + transfer_list_verify[kTransferListHeaderLines + 2];

  // First run: expect the verification to succeed and the last_command_file is intact.
  ASSERT_TRUE(android::base::WriteStringToFile(last_command_content, last_command_file_));

  RunBlockImageUpdate(true, entries, image_file_, "t");

  std::string last_command_actual;
  ASSERT_TRUE(android::base::ReadFileToString(last_command_file_, &last_command_actual));
  EXPECT_EQ(last_command_content, last_command_actual);

  // Second run with a mismatching block image: expect the verification to succeed but
  // last_command_file to be deleted; because the target blocks in the last command don't have the
  // expected contents for the second move command.
  ASSERT_TRUE(android::base::WriteStringToFile(block1 + block2 + block3, image_file_));
  RunBlockImageUpdate(true, entries, image_file_, "t");
  ASSERT_EQ(-1, access(last_command_file_.c_str(), R_OK));
}

class ResumableUpdaterTest : public testing::TestWithParam<size_t> {
 protected:
  void SetUp() override {
    RegisterBuiltins();
    RegisterInstallFunctions();
    RegisterBlockImageFunctions();

    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);

    // Enable a special command "abort" to simulate interruption.
    Command::abort_allowed_ = true;

    index_ = GetParam();
    image_file_ = image_temp_file_.path;
    last_command_file_ = temp_last_command_.path;
  }

  void TearDown() override {
    // Clean up the last_command_file if any.
    ASSERT_TRUE(android::base::RemoveFileIfExists(last_command_file_));

    // Clear partition updated marker if any.
    std::string updated_marker{ temp_stash_base_.path };
    updated_marker += "/" + get_sha1(image_temp_file_.path) + ".UPDATED";
    ASSERT_TRUE(android::base::RemoveFileIfExists(updated_marker));
  }

  TemporaryFile temp_saved_source_;
  TemporaryDir temp_stash_base_;
  std::string last_command_file_;
  std::string image_file_;
  size_t index_;

 private:
  TemporaryFile temp_last_command_;
  TemporaryFile image_temp_file_;
};

static std::string g_source_image;
static std::string g_target_image;
static PackageEntries g_entries;

static std::vector<std::string> GenerateTransferList() {
  std::string a(4096, 'a');
  std::string b(4096, 'b');
  std::string c(4096, 'c');
  std::string d(4096, 'd');
  std::string e(4096, 'e');
  std::string f(4096, 'f');
  std::string g(4096, 'g');
  std::string h(4096, 'h');
  std::string i(4096, 'i');
  std::string zero(4096, '\0');

  std::string a_hash = get_sha1(a);
  std::string b_hash = get_sha1(b);
  std::string c_hash = get_sha1(c);
  std::string e_hash = get_sha1(e);

  auto loc = [](const std::string& range_text) {
    std::vector<std::string> pieces = android::base::Split(range_text, "-");
    size_t left;
    size_t right;
    if (pieces.size() == 1) {
      CHECK(android::base::ParseUint(pieces[0], &left));
      right = left + 1;
    } else {
      CHECK_EQ(2u, pieces.size());
      CHECK(android::base::ParseUint(pieces[0], &left));
      CHECK(android::base::ParseUint(pieces[1], &right));
      right++;
    }
    return android::base::StringPrintf("2,%zu,%zu", left, right);
  };

  // patch 1: "b d c" -> "g"
  TemporaryFile patch_file_bdc_g;
  std::string bdc = b + d + c;
  std::string bdc_hash = get_sha1(bdc);
  std::string g_hash = get_sha1(g);
  CHECK_EQ(0, bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(bdc.data()), bdc.size(),
                             reinterpret_cast<const uint8_t*>(g.data()), g.size(),
                             patch_file_bdc_g.path, nullptr));
  std::string patch_bdc_g;
  CHECK(android::base::ReadFileToString(patch_file_bdc_g.path, &patch_bdc_g));

  // patch 2: "a b c d" -> "d c b"
  TemporaryFile patch_file_abcd_dcb;
  std::string abcd = a + b + c + d;
  std::string abcd_hash = get_sha1(abcd);
  std::string dcb = d + c + b;
  std::string dcb_hash = get_sha1(dcb);
  CHECK_EQ(0, bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(abcd.data()), abcd.size(),
                             reinterpret_cast<const uint8_t*>(dcb.data()), dcb.size(),
                             patch_file_abcd_dcb.path, nullptr));
  std::string patch_abcd_dcb;
  CHECK(android::base::ReadFileToString(patch_file_abcd_dcb.path, &patch_abcd_dcb));

  std::vector<std::string> transfer_list{
    "4",
    "10",  // total blocks written
    "2",   // maximum stash entries
    "2",   // maximum number of stashed blocks

    // a b c d e a b c d e
    "stash " + b_hash + " " + loc("1"),
    // a b c d e a b c d e    [b(1)]
    "stash " + c_hash + " " + loc("2"),
    // a b c d e a b c d e    [b(1)][c(2)]
    "new " + loc("1-2"),
    // a i h d e a b c d e    [b(1)][c(2)]
    "zero " + loc("0"),
    // 0 i h d e a b c d e    [b(1)][c(2)]

    // bsdiff "b d c" (from stash, 3, stash) to get g(3)
    android::base::StringPrintf(
        "bsdiff 0 %zu %s %s %s 3 %s %s %s:%s %s:%s",
        patch_bdc_g.size(),                  // patch start (0), patch length
        bdc_hash.c_str(),                    // source hash
        g_hash.c_str(),                      // target hash
        loc("3").c_str(),                    // target range
        loc("3").c_str(), loc("1").c_str(),  // load "d" from block 3, into buffer at offset 1
        b_hash.c_str(), loc("0").c_str(),    // load "b" from stash, into buffer at offset 0
        c_hash.c_str(), loc("2").c_str()),   // load "c" from stash, into buffer at offset 2

    // 0 i h g e a b c d e    [b(1)][c(2)]
    "free " + b_hash,
    // 0 i h g e a b c d e    [c(2)]
    "free " + a_hash,
    // 0 i h g e a b c d e
    "stash " + a_hash + " " + loc("5"),
    // 0 i h g e a b c d e    [a(5)]
    "move " + e_hash + " " + loc("5") + " 1 " + loc("4"),
    // 0 i h g e e b c d e    [a(5)]

    // bsdiff "a b c d" (from stash, 6-8) to "d c b" (6-8)
    android::base::StringPrintf(  //
        "bsdiff %zu %zu %s %s %s 4 %s %s %s:%s",
        patch_bdc_g.size(),                          // patch start
        patch_bdc_g.size() + patch_abcd_dcb.size(),  // patch length
        abcd_hash.c_str(),                           // source hash
        dcb_hash.c_str(),                            // target hash
        loc("6-8").c_str(),                          // target range
        loc("6-8").c_str(),                          // load "b c d" from blocks 6-8
        loc("1-3").c_str(),                          //   into buffer at offset 1-3
        a_hash.c_str(),                              // load "a" from stash
        loc("0").c_str()),                           //   into buffer at offset 0

    // 0 i h g e e d c b e    [a(5)]
    "new " + loc("4"),
    // 0 i h g f e d c b e    [a(5)]
    "move " + a_hash + " " + loc("9") + " 1 - " + a_hash + ":" + loc("0"),
    // 0 i h g f e d c b a    [a(5)]
    "free " + a_hash,
    // 0 i h g f e d c b a
  };

  std::string new_data = i + h + f;
  std::string patch_data = patch_bdc_g + patch_abcd_dcb;

  g_entries = {
    { "new_data", new_data },
    { "patch_data", patch_data },
  };
  g_source_image = a + b + c + d + e + a + b + c + d + e;
  g_target_image = zero + i + h + g + f + e + d + c + b + a;

  return transfer_list;
}

static const std::vector<std::string> g_transfer_list = GenerateTransferList();

INSTANTIATE_TEST_CASE_P(InterruptAfterEachCommand, ResumableUpdaterTest,
                        ::testing::Range(static_cast<size_t>(0),
                                         g_transfer_list.size() - kTransferListHeaderLines));

TEST_P(ResumableUpdaterTest, InterruptVerifyResume) {
  ASSERT_TRUE(android::base::WriteStringToFile(g_source_image, image_file_));

  LOG(INFO) << "Interrupting at line " << index_ << " ("
            << g_transfer_list[kTransferListHeaderLines + index_] << ")";

  std::vector<std::string> transfer_list_copy{ g_transfer_list };
  transfer_list_copy[kTransferListHeaderLines + index_] = "abort";

  g_entries["transfer_list"] = android::base::Join(transfer_list_copy, '\n');

  // Run update that's expected to fail.
  RunBlockImageUpdate(false, g_entries, image_file_, "");

  std::string last_command_expected;

  // Assert the last_command_file.
  if (index_ == 0) {
    ASSERT_EQ(-1, access(last_command_file_.c_str(), R_OK));
  } else {
    last_command_expected =
        std::to_string(index_ - 1) + "\n" + g_transfer_list[kTransferListHeaderLines + index_ - 1];
    std::string last_command_actual;
    ASSERT_TRUE(android::base::ReadFileToString(last_command_file_, &last_command_actual));
    ASSERT_EQ(last_command_expected, last_command_actual);
  }

  g_entries["transfer_list"] = android::base::Join(g_transfer_list, '\n');

  // Resume the interrupted update, by doing verification first.
  RunBlockImageUpdate(true, g_entries, image_file_, "t");

  // last_command_file should remain intact.
  if (index_ == 0) {
    ASSERT_EQ(-1, access(last_command_file_.c_str(), R_OK));
  } else {
    std::string last_command_actual;
    ASSERT_TRUE(android::base::ReadFileToString(last_command_file_, &last_command_actual));
    ASSERT_EQ(last_command_expected, last_command_actual);
  }

  // Resume the update.
  RunBlockImageUpdate(false, g_entries, image_file_, "t");

  // last_command_file should be gone after successful update.
  ASSERT_EQ(-1, access(last_command_file_.c_str(), R_OK));

  std::string updated_image_actual;
  ASSERT_TRUE(android::base::ReadFileToString(image_file_, &updated_image_actual));
  ASSERT_EQ(g_target_image, updated_image_actual);
}
