// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/process/launch.h>
#include <base/test/scoped_chromeos_version_info.h>
#include <brillo/files/file_util.h>
#include <gtest/gtest.h>

#include "installer/inst_util.h"
#include "installer/mock_cgpt_manager.h"
#include "installer/mock_metrics.h"
#include "installer/reven_partition_migration.h"
#include "installer/reven_partition_migration_private.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::StrictMock;

namespace {

uint64_t MibToBytes(uint64_t mib) {
  return mib * 1024 * 1024;
}

// Use truncate to create a sparse file.
void TruncateFile(const base::FilePath& path, const std::string& size) {
  std::string output;
  EXPECT_TRUE(base::GetAppOutput(
      base::CommandLine({"truncate", "--size=" + size, path.value()}),
      &output));
}

struct ComparePartitionNum {
  bool operator()(const PartitionNum& a, const PartitionNum& b) const {
    return a.Value() < b.Value();
  }
};

class MockEnvironment : public base::Environment {
 public:
  MOCK_METHOD(bool,
              GetVar,
              (base::StringPiece variable_name, std::string* result),
              (override));
  MOCK_METHOD(bool, HasVar, (base::StringPiece variable_name), (override));
  MOCK_METHOD(bool,
              SetVar,
              (base::StringPiece variable_name, const std::string& new_value),
              (override));
  MOCK_METHOD(bool, UnSetVar, (base::StringPiece variable_name), (override));
};

class PartitionMigrationTest : public ::testing::Test {
 protected:
  void SetUp() {
    EXPECT_TRUE(tmp_dir_.CreateUniqueTempDir());
    disk_path_ = tmp_dir_.GetPath().Append("disk");
    TruncateFile(disk_path_, "10GiB");

    EXPECT_CALL(cgpt_manager_, DeviceName())
        .WillRepeatedly(ReturnRef(disk_path_));

    // Numbers from a reven 113 install (`cgpt show`).
    orig_partitions_[PartitionNum::KERN_A] = {69, 32768};
    orig_partitions_[PartitionNum::ROOT_A] = {8884224, 8388608};
    orig_partitions_[PartitionNum::KERN_B] = {32837, 32768};
    orig_partitions_[PartitionNum::ROOT_B] = {495616, 8388608};

    // Write some to the kernel partitions to validate it gets copied
    // properly.
    InitializeKernelData();
    WriteKernelData(orig_partitions_[PartitionNum::KERN_A].start);
    WriteKernelData(orig_partitions_[PartitionNum::KERN_B].start);

    EXPECT_CALL(cgpt_manager_, GetSectorRange(_, _))
        .WillRepeatedly(Invoke(this, &PartitionMigrationTest::GetSectorRange));
  }

  // Write the 16MiB test kernel data to the fake disk, beginning at
  // `start_sector`.
  void WriteKernelData(uint64_t start_sector) {
    base::File disk_file(disk_path_,
                         base::File::FLAG_OPEN | base::File::FLAG_WRITE);
    EXPECT_TRUE(
        disk_file.WriteAndCheck(SectorsToBytes(start_sector), kernel_data_));
  }

  // Check that the new kernel partition's data was properly initialized.
  void CheckNewKernelData(PartitionNum kern_num) {
    PartitionNum root_num(kern_num.Value() + 1);
    base::File disk_file(disk_path_,
                         base::File::FLAG_OPEN | base::File::FLAG_READ);
    std::vector<uint8_t> new_kernel_data;
    new_kernel_data.resize(MibToBytes(64));
    EXPECT_TRUE(disk_file.ReadAndCheck(
        SectorsToBytes(orig_partitions_[root_num].start +
                       orig_partitions_[root_num].count - MibToSectors(64)),
        new_kernel_data));

    std::vector<uint8_t> expected_kernel_data = kernel_data_;
    expected_kernel_data.resize(new_kernel_data.size(), 0);
    EXPECT_EQ(new_kernel_data, expected_kernel_data);
  }

  void ExpectMetric(PartitionMigrationResult result) {
    EXPECT_CALL(metrics_, SendEnumMetric(_, static_cast<int>(result), _))
        .WillOnce(Return(true));
  }

  void SetIsInstall(bool is_install) {
    EXPECT_CALL(env_, HasVar(base::StringPiece(kEnvIsInstall)))
        .WillOnce(Return(is_install));
  }

  void ExpectSlotAMigration() {
    SectorRange root_a = orig_partitions_[PartitionNum::ROOT_A];

    // Kernel is now the last 64MiB of the original root partition.
    EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::KERN_A,
                                              Eq(root_a.start + root_a.count -
                                                 MibToSectors(64)),
                                              Eq(MibToSectors(64))))
        .WillOnce(Return(CgptErrorCode::kSuccess));
    EXPECT_CALL(cgpt_manager_,
                SetSectorRange(PartitionNum::ROOT_A, Eq(std::nullopt),
                               Eq(root_a.count - MibToSectors(64))))
        .WillOnce(Return(CgptErrorCode::kSuccess));
  }

  void ExpectSlotBMigration() {
    SectorRange root_b = orig_partitions_[PartitionNum::ROOT_B];

    // Kernel is now the last 64MiB of the original root partition.
    EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::KERN_B,
                                              Eq(root_b.start + root_b.count -
                                                 MibToSectors(64)),
                                              Eq(MibToSectors(64))))
        .WillOnce(Return(CgptErrorCode::kSuccess));
    EXPECT_CALL(cgpt_manager_,
                SetSectorRange(PartitionNum::ROOT_B, Eq(std::nullopt),
                               Eq(root_b.count - MibToSectors(64))))
        .WillOnce(Return(CgptErrorCode::kSuccess));
  }

  base::ScopedTempDir tmp_dir_;
  base::FilePath disk_path_;
  std::map<PartitionNum, SectorRange, ComparePartitionNum> orig_partitions_;

  // Use StrictMock for cgpt_manager because we care about not having
  // any unexpected calls that modify the disk. Also use StrictMock for
  // the other interfaces, since they are very minimal and unlikely to
  // break.
  StrictMock<MockCgptManager> cgpt_manager_;
  StrictMock<MockEnvironment> env_;
  StrictMock<MockMetrics> metrics_;

 private:
  void InitializeKernelData() {
    kernel_data_.resize(MibToBytes(16));  // 16MiB

    uint8_t val = 1;
    for (uint8_t& byte : kernel_data_) {
      byte = val;
      val++;
    }
  }

  CgptErrorCode GetSectorRange(PartitionNum num, SectorRange& sectors) {
    const auto it = orig_partitions_.find(num);
    if (it == orig_partitions_.end()) {
      return CgptErrorCode::kUnknownError;
    }

    sectors = it->second;
    return CgptErrorCode::kSuccess;
  }

  std::vector<uint8_t> kernel_data_;
};

}  // namespace

// Tests for errors in creating a `SlotPlan`:

TEST_F(PartitionMigrationTest, SlotPlanInitializeGptReadKernError) {
  orig_partitions_.erase(PartitionNum::KERN_A);

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(),
            PartitionMigrationResult::kGptReadKernError);
}

TEST_F(PartitionMigrationTest, SlotPlanInitializeGptReadRootError) {
  orig_partitions_.erase(PartitionNum::ROOT_A);

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(),
            PartitionMigrationResult::kGptReadRootError);
}

TEST_F(PartitionMigrationTest, SlotPlanInitializeRootUnexpectedSize) {
  orig_partitions_[PartitionNum::ROOT_A].count = MibToSectors(3047);

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(),
            PartitionMigrationResult::kRootPartitionUnexpectedSize);
}

TEST_F(PartitionMigrationTest, SlotPlanInitializeNoMigrationNeeded) {
  orig_partitions_[PartitionNum::KERN_A].count = MibToSectors(64);

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(),
            PartitionMigrationResult::kNoMigrationNeeded);
}

// Tests for errors when running a migration on one slot:

TEST_F(PartitionMigrationTest, SlotPlanRunDiskOpenError) {
  EXPECT_TRUE(brillo::DeleteFile(disk_path_));

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(), PartitionMigrationResult::kSuccess);
  EXPECT_EQ(slot_plan.Run(), PartitionMigrationResult::kDiskOpenError);
}

TEST_F(PartitionMigrationTest, SlotPlanRunDiskReadError) {
  EXPECT_TRUE(base::WriteFile(disk_path_, ""));

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(), PartitionMigrationResult::kSuccess);
  EXPECT_EQ(slot_plan.Run(), PartitionMigrationResult::kDiskReadError);
}

TEST_F(PartitionMigrationTest, SlotPlanRunGptWriteRootError) {
  EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::ROOT_A, _, _))
      .WillOnce(Return(CgptErrorCode::kUnknownError));

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(), PartitionMigrationResult::kSuccess);
  EXPECT_EQ(slot_plan.Run(), PartitionMigrationResult::kGptWriteRootError);
}

TEST_F(PartitionMigrationTest, SlotPlanRunGptWriteKernError) {
  EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::ROOT_A, _, _))
      .WillOnce(Return(CgptErrorCode::kSuccess));
  EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::KERN_A, _, _))
      .WillOnce(Return(CgptErrorCode::kUnknownError));

  SlotPlan slot_plan = SlotPlan::ForSlotA(cgpt_manager_);
  EXPECT_EQ(slot_plan.Initialize(), PartitionMigrationResult::kSuccess);
  EXPECT_EQ(slot_plan.Run(), PartitionMigrationResult::kGptWriteKernError);
}

// Note: no test for kDiskWriteError, since it's difficult to force a
// write error to occur in a test without also making the file open
// fail.

// Tests for a successful migration of one or both slots:

TEST_F(PartitionMigrationTest, RunSuccess) {
  SetIsInstall(true);
  ExpectSlotAMigration();
  ExpectSlotBMigration();
  ExpectMetric(PartitionMigrationResult::kSuccess);

  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));

  CheckNewKernelData(PartitionNum::KERN_A);
  CheckNewKernelData(PartitionNum::KERN_B);
}

TEST_F(PartitionMigrationTest, RunSuccessCloudReady96) {
  SetIsInstall(true);

  // Numbers from a beerover 96.4 install (`cgpt show`).
  orig_partitions_[PartitionNum::KERN_A] = {20480, 32768};
  orig_partitions_[PartitionNum::ROOT_A] = {6623232, 6242304};
  orig_partitions_[PartitionNum::KERN_B] = {53248, 32768};
  orig_partitions_[PartitionNum::ROOT_B] = {380928, 6242304};

  WriteKernelData(orig_partitions_[PartitionNum::KERN_A].start);
  WriteKernelData(orig_partitions_[PartitionNum::KERN_B].start);

  ExpectSlotAMigration();
  ExpectSlotBMigration();
  ExpectMetric(PartitionMigrationResult::kSuccess);

  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));

  CheckNewKernelData(PartitionNum::KERN_A);
  CheckNewKernelData(PartitionNum::KERN_B);
}

TEST_F(PartitionMigrationTest, RunNoMigrationNeeded) {
  SetIsInstall(true);
  orig_partitions_[PartitionNum::KERN_A].count = MibToSectors(64);
  orig_partitions_[PartitionNum::KERN_B].count = MibToSectors(64);

  ExpectMetric(PartitionMigrationResult::kNoMigrationNeeded);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

TEST_F(PartitionMigrationTest, RunSlotANoMigrationNeeded) {
  SetIsInstall(true);
  orig_partitions_[PartitionNum::KERN_A].count = MibToSectors(64);

  ExpectSlotBMigration();

  ExpectMetric(PartitionMigrationResult::kSuccess);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

TEST_F(PartitionMigrationTest, RunSlotBNoMigrationNeeded) {
  SetIsInstall(true);
  orig_partitions_[PartitionNum::KERN_B].count = MibToSectors(64);

  ExpectSlotAMigration();

  ExpectMetric(PartitionMigrationResult::kSuccess);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

// Tests for how errors are handled if either slot plan fails to
// initialize. An error metric should be sent, but postinstall should be
// allowed to proceed (RunRevenPartitionMigration returns true).

TEST_F(PartitionMigrationTest, RunSlotAPlanError) {
  SetIsInstall(true);
  orig_partitions_.erase(PartitionNum::KERN_A);

  ExpectMetric(PartitionMigrationResult::kGptReadKernError);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

TEST_F(PartitionMigrationTest, RunSlotBPlanError) {
  SetIsInstall(true);
  orig_partitions_.erase(PartitionNum::KERN_B);

  ExpectMetric(PartitionMigrationResult::kGptReadKernError);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

// Tests for propagating errors if either slot migration fails:

TEST_F(PartitionMigrationTest, RunSlotAMigrationError) {
  SetIsInstall(true);

  // Arbitrary choice of failure in the slot A migration.
  EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::ROOT_A, _, _))
      .WillOnce(Return(CgptErrorCode::kUnknownError));

  ExpectMetric(PartitionMigrationResult::kGptWriteRootError);
  EXPECT_FALSE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

TEST_F(PartitionMigrationTest, RunSlotBMigrationError) {
  SetIsInstall(true);

  // Arbitrary choice of failure in the slot B migration.
  EXPECT_CALL(cgpt_manager_, SetSectorRange(PartitionNum::ROOT_B, _, _))
      .WillOnce(Return(CgptErrorCode::kUnknownError));

  // The Slot A migration has already happened by the time we get to the
  // failure on the B slot.
  ExpectSlotAMigration();

  ExpectMetric(PartitionMigrationResult::kGptWriteRootError);
  EXPECT_FALSE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

// Test that no migration occurs during updates (except on particular
// channels). This behavior will change in the future, but for now we
// only run the migration on install.
TEST_F(PartitionMigrationTest, NotRunningFromInstaller) {
  SetIsInstall(false);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

// Test that migration planning does occur during updates, even if the
// migration doesn't run.
TEST_F(PartitionMigrationTest, UpdatePlanningOccurs) {
  SetIsInstall(false);

  orig_partitions_[PartitionNum::KERN_A].count = MibToSectors(64);
  orig_partitions_[PartitionNum::KERN_B].count = MibToSectors(64);

  ExpectMetric(PartitionMigrationResult::kNoMigrationNeeded);
  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));
}

// Test that migration runs during updates when the payload is a test image.
TEST_F(PartitionMigrationTest, UpdateMigrationOnTest) {
  base::test::ScopedChromeOSVersionInfo scoped_info(
      "CHROMEOS_RELEASE_TRACK=testimage-channel\n", base::Time::Now());

  SetIsInstall(false);

  ExpectSlotAMigration();
  ExpectSlotBMigration();
  ExpectMetric(PartitionMigrationResult::kSuccess);

  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));

  CheckNewKernelData(PartitionNum::KERN_A);
  CheckNewKernelData(PartitionNum::KERN_B);
}

// Test that migration runs during updates when the payload is on canary.
TEST_F(PartitionMigrationTest, UpdateMigrationOnCanary) {
  base::test::ScopedChromeOSVersionInfo scoped_info(
      "CHROMEOS_RELEASE_TRACK=canary-channel\n", base::Time::Now());

  SetIsInstall(false);

  ExpectSlotAMigration();
  ExpectSlotBMigration();
  ExpectMetric(PartitionMigrationResult::kSuccess);

  EXPECT_TRUE(RunRevenPartitionMigration(cgpt_manager_, metrics_, env_));

  CheckNewKernelData(PartitionNum::KERN_A);
  CheckNewKernelData(PartitionNum::KERN_B);
}

TEST(PartitionMigration, MibToSectors) {
  EXPECT_EQ(MibToSectors(0), 0);
  EXPECT_EQ(MibToSectors(1), 2048);
  EXPECT_EQ(MibToSectors(4096), 8388608);
}

TEST(PartitionMigration, SectorsToBytes) {
  EXPECT_EQ(SectorsToBytes(0), 0);
  EXPECT_EQ(SectorsToBytes(1), 512);
  EXPECT_EQ(SectorsToBytes(4096), 2097152);
}
