// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modemfwd/modem_flasher.h"

#include <memory>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <chromeos/switches/modemfwd_switches.h>
#include <gtest/gtest.h>

#include "modemfwd/firmware_directory_stub.h"
#include "modemfwd/mock_journal.h"
#include "modemfwd/mock_modem.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Mock;
using ::testing::Return;

namespace modemfwd {

namespace {

constexpr char kDeviceId1[] = "device:id:1";
constexpr char kEquipmentId1[] = "equipment_id_1";

constexpr char kMainFirmware1Path[] = "main_fw_1.fls";
constexpr char kMainFirmware1Version[] = "versionA";

constexpr char kMainFirmware2Path[] = "main_fw_2.fls";
constexpr char kMainFirmware2Version[] = "versionB";

constexpr char kOemFirmware1Path[] = "oem_cust_1.fls";
constexpr char kOemFirmware1Version[] = "6000.1";

constexpr char kOemFirmware2Path[] = "oem_cust_2.fls";
constexpr char kOemFirmware2Version[] = "6000.2";

constexpr char kCarrier1[] = "uuid_1";
constexpr char kCarrier1Mvno[] = "uuid_1_1";
constexpr char kCarrier1Firmware1Path[] = "carrier_1_fw_1.fls";
constexpr char kCarrier1Firmware1Version[] = "v1.00";
constexpr char kCarrier1Firmware2Path[] = "carrier_1_fw_2.fls";
constexpr char kCarrier1Firmware2Version[] = "v1.10";

constexpr char kCarrier2[] = "uuid_2";
constexpr char kCarrier2Firmware1Path[] = "carrier_2_fw_1.fls";
constexpr char kCarrier2Firmware1Version[] = "4500.15.65";

constexpr char kGenericCarrierFirmware1Path[] = "generic_fw_1.fls";
constexpr char kGenericCarrierFirmware1Version[] = "2017-10-13";
constexpr char kGenericCarrierFirmware2Path[] = "generic_fw_2.fls";
constexpr char kGenericCarrierFirmware2Version[] = "2017-10-14";

}  // namespace

class ModemFlasherTest : public ::testing::Test {
 public:
  ModemFlasherTest() {
    auto firmware_directory = std::make_unique<FirmwareDirectoryStub>();
    firmware_directory_ = firmware_directory.get();

    auto journal = std::make_unique<MockJournal>();
    journal_ = journal.get();

    modem_flasher_ = std::make_unique<ModemFlasher>(
        std::move(firmware_directory), std::move(journal));

    only_main_ = {kFwMain};
    only_carrier_ = {kFwCarrier};
  }

 protected:
  void AddMainFirmwareFile(const std::string& device_id,
                           const base::FilePath& firmware_path,
                           const std::string& version) {
    FirmwareFileInfo firmware_info(firmware_path, version);
    firmware_directory_->AddMainFirmware(kDeviceId1, firmware_info);
  }

  void AddMainFirmwareFileForCarrier(const std::string& device_id,
                                     const std::string& carrier_name,
                                     const base::FilePath& firmware_path,
                                     const std::string& version) {
    FirmwareFileInfo firmware_info(firmware_path, version);
    firmware_directory_->AddMainFirmwareForCarrier(kDeviceId1, carrier_name,
                                                   firmware_info);
  }

  void AddOemFirmwareFile(const std::string& device_id,
                          const base::FilePath& firmware_path,
                          const std::string& version) {
    FirmwareFileInfo firmware_info(firmware_path, version);
    firmware_directory_->AddOemFirmware(kDeviceId1, firmware_info);
  }

  void AddOemFirmwareFileForCarrier(const std::string& device_id,
                                    const std::string& carrier_name,
                                    const base::FilePath& firmware_path,
                                    const std::string& version) {
    FirmwareFileInfo firmware_info(firmware_path, version);
    firmware_directory_->AddOemFirmwareForCarrier(kDeviceId1, carrier_name,
                                                  firmware_info);
  }

  void AddCarrierFirmwareFile(const std::string& device_id,
                              const std::string& carrier_name,
                              const base::FilePath& firmware_path,
                              const std::string& version) {
    FirmwareFileInfo firmware_info(firmware_path, version);
    firmware_directory_->AddCarrierFirmware(kDeviceId1, carrier_name,
                                            firmware_info);
  }

  std::unique_ptr<MockModem> GetDefaultModem() {
    auto modem = std::make_unique<MockModem>();
    ON_CALL(*modem, GetDeviceId()).WillByDefault(Return(kDeviceId1));
    ON_CALL(*modem, GetEquipmentId()).WillByDefault(Return(kEquipmentId1));
    ON_CALL(*modem, GetCarrierId()).WillByDefault(Return(kCarrier1));
    ON_CALL(*modem, GetMainFirmwareVersion())
        .WillByDefault(Return(kMainFirmware1Version));
    ON_CALL(*modem, GetOemFirmwareVersion())
        .WillByDefault(Return(kOemFirmware1Version));
    ON_CALL(*modem, GetCarrierFirmwareId()).WillByDefault(Return(""));
    ON_CALL(*modem, GetCarrierFirmwareVersion()).WillByDefault(Return(""));

    // Since the equipment ID is the main identifier we should always expect
    // to want to know what it is.
    EXPECT_CALL(*modem, GetEquipmentId()).Times(AtLeast(1));
    return modem;
  }

  void SetCarrierFirmwareInfo(MockModem* modem,
                              const std::string& carrier_id,
                              const std::string& version) {
    ON_CALL(*modem, GetCarrierFirmwareId()).WillByDefault(Return(carrier_id));
    ON_CALL(*modem, GetCarrierFirmwareVersion()).WillByDefault(Return(version));
  }

  MockJournal* journal_;
  std::unique_ptr<ModemFlasher> modem_flasher_;
  // helpers for the mock_journal calls
  std::vector<std::string> only_main_;
  std::vector<std::string> only_carrier_;

 private:
  // We pass this off to |modem_flasher_| but keep a reference to it to ensure
  // we can set up the stub outputs.
  FirmwareDirectoryStub* firmware_directory_;
};

TEST_F(ModemFlasherTest, NothingToFlash) {
  auto modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, FlashMainFirmware) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, FlashMainFirmwareEmptyCarrier) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  ON_CALL(*modem, GetCarrierId()).WillByDefault(Return(""));

  // Flash the main fw even when the carrier is unknown
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, SkipSameMainVersion) {
  base::FilePath firmware(kMainFirmware1Path);
  AddMainFirmwareFile(kDeviceId1, firmware, kMainFirmware1Version);

  auto modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, SkipSameOemVersion) {
  base::FilePath firmware(kOemFirmware1Path);
  AddOemFirmwareFile(kDeviceId1, firmware, kOemFirmware1Version);

  auto modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetOemFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, UpgradeOemFirmware) {
  base::FilePath new_firmware(kOemFirmware2Path);
  AddOemFirmwareFile(kDeviceId1, new_firmware, kOemFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> oem_cfg = {
      {kFwOem, new_firmware, kOemFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetOemFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(oem_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, UpgradeCarrierFirmware) {
  base::FilePath new_firmware(kCarrier1Firmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, new_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kCarrier1Firmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, SwitchCarrierFirmwareForSimHotSwap) {
  base::FilePath original_firmware(kCarrier1Firmware1Path);
  base::FilePath other_firmware(kCarrier2Firmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, original_firmware,
                         kCarrier1Firmware1Version);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier2, other_firmware,
                         kCarrier2Firmware1Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_other_cfg = {
      {kFwCarrier, other_firmware, kCarrier2Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier2));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_other_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // After the modem reboots, the helper hopefully reports the new carrier.
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());

  // Suppose we swap the SIM back to the first one. Then we should try to
  // flash the first firmware again.
  modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_orig_cfg = {
      {kFwCarrier, original_firmware, kCarrier1Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_orig_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, BlockAfterMainFlashFailure) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillRepeatedly(Return(false));
  modem_flasher_->TryFlash(modem.get());

  // ModemFlasher retries once on a failure, so fail twice.
  modem = GetDefaultModem();
  modem_flasher_->TryFlash(modem.get());

  // Here the modem would reboot, but ModemFlasher should keep track of its
  // IMEI and ensure we don't even check the main firmware version or
  // carrier.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(0);
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(0);
  EXPECT_CALL(*modem, GetCarrierId()).Times(0);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, BlockAfterCarrierFlashFailure) {
  base::FilePath new_firmware(kCarrier1Firmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, new_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kCarrier1Firmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg))
      .WillRepeatedly(Return(false));
  modem_flasher_->TryFlash(modem.get());

  // ModemFlasher retries once on a failure, so fail twice.
  modem = GetDefaultModem();
  modem_flasher_->TryFlash(modem.get());

  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(0);
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(0);
  EXPECT_CALL(*modem, GetCarrierId()).Times(0);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, RefuseToFlashMainFirmwareTwice) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // We've had issues in the past where the firmware version is updated
  // but the modem still reports the old version string. Refuse to flash
  // the main firmware twice because that should never be correct behavior
  // in one session. Otherwise, we might try to flash the main firmware
  // over and over.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(0);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, RefuseToFlashOemFirmwareTwice) {
  base::FilePath new_firmware(kOemFirmware2Path);
  AddOemFirmwareFile(kDeviceId1, new_firmware, kOemFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> oem_cfg = {
      {kFwOem, new_firmware, kOemFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetOemFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(oem_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // Assume that the modem fails to return properly the new version.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetOemFirmwareVersion()).Times(0);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, RefuseToFlashCarrierFirmwareTwice) {
  base::FilePath new_firmware(kCarrier1Firmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, new_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kCarrier1Firmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // Assume the carrier firmware doesn't have an updated version string in it,
  // i.e. the modem will return the old version string even if it's been
  // updated.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, RefuseToReflashCarrierAcrossHotSwap) {
  // Upgrade carrier firmware.
  base::FilePath new_firmware(kCarrier1Firmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, new_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kCarrier1Firmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // Switch carriers, but there won't be firmware for the new one.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier2));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware2Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());

  // Suppose we swap the SIM back to the first one. We should not flash
  // firmware that we already know we successfully flashed.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware2Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, UpgradeGenericFirmware) {
  base::FilePath new_firmware(kGenericCarrierFirmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, FirmwareDirectory::kGenericCarrierId,
                         new_firmware, kGenericCarrierFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kGenericCarrierFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), FirmwareDirectory::kGenericCarrierId,
                         kGenericCarrierFirmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, SkipSameGenericFirmware) {
  base::FilePath generic_firmware(kGenericCarrierFirmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, FirmwareDirectory::kGenericCarrierId,
                         generic_firmware, kGenericCarrierFirmware1Version);

  auto modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), FirmwareDirectory::kGenericCarrierId,
                         kGenericCarrierFirmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, TwoCarriersUsingGenericFirmware) {
  base::FilePath generic_firmware(kGenericCarrierFirmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, FirmwareDirectory::kGenericCarrierId,
                         generic_firmware, kGenericCarrierFirmware1Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, generic_firmware, kGenericCarrierFirmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // When we try to flash again and the modem reports a different carrier,
  // we should expect that the ModemFlasher refuses to flash the same firmware,
  // since there is generic firmware and no carrier has its own firmware.
  modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), FirmwareDirectory::kGenericCarrierId,
                         kGenericCarrierFirmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, HotSwapWithGenericFirmware) {
  base::FilePath original_firmware(kGenericCarrierFirmware1Path);
  base::FilePath other_firmware(kCarrier2Firmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, FirmwareDirectory::kGenericCarrierId,
                         original_firmware, kGenericCarrierFirmware1Version);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier2, other_firmware,
                         kCarrier2Firmware1Version);

  // Even though there is generic firmware, we should try to use specific
  // ones first if they exist.
  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_other_cfg = {
      {kFwCarrier, other_firmware, kCarrier2Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier2));
  SetCarrierFirmwareInfo(modem.get(), FirmwareDirectory::kGenericCarrierId,
                         kGenericCarrierFirmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_other_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // Reboot the modem.
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());

  // Suppose we swap the SIM back to the first one. Then we should try to
  // flash the generic firmware again.
  modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_orig_cfg = {
      {kFwCarrier, original_firmware, kGenericCarrierFirmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_orig_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, WritesToJournal) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(true));
  EXPECT_CALL(*journal_, MarkStartOfFlashingFirmware(only_main_, kDeviceId1, _))
      .Times(1);
  EXPECT_CALL(*journal_, MarkEndOfFlashingFirmware(kDeviceId1, _)).Times(1);
  base::OnceClosure cb = modem_flasher_->TryFlash(modem.get());
  // The cleanup callback marks the end of flashing the firmware.
  ASSERT_FALSE(cb.is_null());
  std::move(cb).Run();
}

TEST_F(ModemFlasherTest, WritesToJournalOnFailure) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(false));
  EXPECT_CALL(*journal_, MarkStartOfFlashingFirmware(only_main_, kDeviceId1, _))
      .Times(1);
  EXPECT_CALL(*journal_, MarkEndOfFlashingFirmware(kDeviceId1, _)).Times(1);
  // There should be no journal cleanup after the flashing fails.
  base::OnceClosure cb = modem_flasher_->TryFlash(modem.get());
  ASSERT_TRUE(cb.is_null());
}

TEST_F(ModemFlasherTest, WritesCarrierSwitchesToJournal) {
  base::FilePath original_firmware(kCarrier1Firmware1Path);
  base::FilePath other_firmware(kCarrier2Firmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, original_firmware,
                         kCarrier1Firmware1Version);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier2, other_firmware,
                         kCarrier2Firmware1Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_other_cfg = {
      {kFwCarrier, other_firmware, kCarrier2Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier2));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_other_cfg)).WillOnce(Return(true));
  EXPECT_CALL(*journal_,
              MarkStartOfFlashingFirmware(only_carrier_, kDeviceId1, kCarrier2))
      .Times(1);
  EXPECT_CALL(*journal_, MarkEndOfFlashingFirmware(kDeviceId1, kCarrier2))
      .Times(1);
  base::OnceClosure cb = modem_flasher_->TryFlash(modem.get());
  ASSERT_FALSE(cb.is_null());
  std::move(cb).Run();

  // After the modem reboots, the helper hopefully reports the new carrier.
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  cb = modem_flasher_->TryFlash(modem.get());
  ASSERT_TRUE(cb.is_null());

  // Suppose we swap the SIM back to the first one. Then we should try to
  // flash the first firmware again.
  modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_orig_cfg = {
      {kFwCarrier, original_firmware, kCarrier1Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_orig_cfg)).WillOnce(Return(true));
  EXPECT_CALL(*journal_,
              MarkStartOfFlashingFirmware(only_carrier_, kDeviceId1, kCarrier1))
      .Times(1);
  EXPECT_CALL(*journal_, MarkEndOfFlashingFirmware(kDeviceId1, kCarrier1))
      .Times(1);
  cb = modem_flasher_->TryFlash(modem.get());
  ASSERT_FALSE(cb.is_null());
  std::move(cb).Run();
}

TEST_F(ModemFlasherTest, CarrierSwitchingMainFirmware) {
  base::FilePath original_main(kMainFirmware1Path);
  AddMainFirmwareFile(kDeviceId1, original_main, kMainFirmware1Version);
  base::FilePath other_main(kMainFirmware2Path);
  AddMainFirmwareFileForCarrier(kDeviceId1, kCarrier2, other_main,
                                kMainFirmware2Version);

  base::FilePath original_oem(kOemFirmware1Path);
  AddOemFirmwareFile(kDeviceId1, original_oem, kOemFirmware1Version);
  base::FilePath other_oem(kOemFirmware2Path);
  AddOemFirmwareFileForCarrier(kDeviceId1, kCarrier2, other_oem,
                               kOemFirmware2Version);

  base::FilePath original_carrier(kCarrier1Firmware1Path);
  base::FilePath other_carrier(kCarrier2Firmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, original_carrier,
                         kCarrier1Firmware1Version);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier2, other_carrier,
                         kCarrier2Firmware1Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> other_cfg = {
      {kFwMain, other_main, kMainFirmware2Version},
      {kFwOem, other_oem, kOemFirmware2Version},
      {kFwCarrier, other_carrier, kCarrier2Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier2));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(other_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());

  // Switch the carrier back and make sure we flash all firmware blobs
  // again.
  modem = GetDefaultModem();
  std::vector<FirmwareConfig> orig_cfg = {
      {kFwMain, original_main, kMainFirmware1Version},
      {kFwOem, original_oem, kOemFirmware1Version},
      {kFwCarrier, original_carrier, kCarrier1Firmware1Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kMainFirmware2Version));
  EXPECT_CALL(*modem, GetOemFirmwareVersion())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kOemFirmware2Version));
  EXPECT_CALL(*modem, GetCarrierId())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(kCarrier1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier2, kCarrier2Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(orig_cfg)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, InhibitDuringMainFirmwareFlash) {
  base::FilePath new_firmware(kMainFirmware2Path);
  AddMainFirmwareFile(kDeviceId1, new_firmware, kMainFirmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> main_cfg = {
      {kFwMain, new_firmware, kMainFirmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetMainFirmwareVersion()).Times(AtLeast(1));
  EXPECT_CALL(*modem, FlashFirmwares(main_cfg)).WillOnce(Return(true));
  EXPECT_CALL(*modem, SetInhibited(true)).WillOnce(Return(true));
  EXPECT_CALL(*modem, SetInhibited(false)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, InhibitDuringCarrierFirmwareFlash) {
  base::FilePath new_firmware(kCarrier1Firmware2Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, new_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  std::vector<FirmwareConfig> carrier_cfg = {
      {kFwCarrier, new_firmware, kCarrier1Firmware2Version}};
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  SetCarrierFirmwareInfo(modem.get(), kCarrier1, kCarrier1Firmware1Version);
  EXPECT_CALL(*modem, FlashFirmwares(carrier_cfg)).WillOnce(Return(true));
  EXPECT_CALL(*modem, SetInhibited(true)).WillOnce(Return(true));
  EXPECT_CALL(*modem, SetInhibited(false)).WillOnce(Return(true));
  modem_flasher_->TryFlash(modem.get());
}

TEST_F(ModemFlasherTest, SkipCarrierWithTwoUuidSameFirmware) {
  base::FilePath current_firmware(kCarrier1Firmware1Path);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1, current_firmware,
                         kCarrier1Firmware2Version);
  AddCarrierFirmwareFile(kDeviceId1, kCarrier1Mvno, current_firmware,
                         kCarrier1Firmware2Version);

  auto modem = GetDefaultModem();
  EXPECT_CALL(*modem, GetDeviceId()).Times(AtLeast(1));
  EXPECT_CALL(*modem, GetCarrierFirmwareVersion()).Times(AtLeast(1));
  // The modem will say that the currently flashed firmware has the carrier UUID
  // KCarrier1Mvno while the current carrier UUID is always returned as
  // kCarrier1.
  SetCarrierFirmwareInfo(modem.get(), kCarrier1Mvno, kCarrier1Firmware2Version);
  EXPECT_CALL(*modem, FlashFirmwares(_)).Times(0);
  modem_flasher_->TryFlash(modem.get());
}

}  // namespace modemfwd
