/*
 * 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 std::string& expr_str, CauseCode cause_code,
                   UpdaterInfo* info = nullptr) {
  std::unique_ptr<Expr> e;
  int error_count = 0;
  ASSERT_EQ(0, ParseString(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, 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, 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, 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, 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, kNoCause);

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

  cmd = "apply_patch_check(\"" + filename_bad + "\", \"wrong_sha1\", \"" + src_hash +
        "\", \"wrong_sha2\")";
  expect("t", cmd, 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, kNoCause);

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

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

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

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

    std::string script6("file_getprop(\"" + std::string(temp_file2.path) +
                       "\", \"ro.product.model\")");
    expect("", script6, 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, 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, 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, kNoCause, &updater_info);

  // Extract to /dev/full should fail.
  script = "package_extract_file(\"a.txt\", \"/dev/full\")";
  expect("", script, 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, kNoCause, &updater_info);

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

  // Missing entry. The one-argument version aborts the evaluation.
  script = "package_extract_file(\"doesntexist\")";
  expect(nullptr, script, 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, 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, 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, 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, kNoCause);

  // Bad BCB path.
  script = "get_stage(\"doesntexist\")";
  expect("", script, 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, 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, kNoCause);

  script = "set_stage(\"/dev/full\", \"1/3\")";
  expect("", script, 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);
}
