// Copyright 2017 The ChromiumOS Authors
// 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 <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/switches/modemfwd_switches.h>
#include <dbus/modemfwd/dbus-constants.h>

#include "modemfwd/error.h"
#include "modemfwd/firmware_file.h"
#include "modemfwd/logging.h"
#include "modemfwd/metrics.h"
#include "modemfwd/modem.h"
#include "modemfwd/notification_manager.h"

namespace modemfwd {

namespace {

class InhibitMode {
 public:
  explicit InhibitMode(Modem* modem) : modem_(modem) {
    if (!modem_->SetInhibited(true))
      ELOG(INFO) << "Inhibiting failed";
  }
  ~InhibitMode() {
    if (!modem_->SetInhibited(false))
      ELOG(INFO) << "Uninhibiting failed";
  }

 private:
  Modem* modem_;
};

std::string GetFirmwareVersion(Modem* modem, std::string type) {
  if (type == kFwMain)
    return modem->GetMainFirmwareVersion();
  else if (type == kFwCarrier)
    return modem->GetCarrierFirmwareVersion();
  else if (type == kFwOem)
    return modem->GetOemFirmwareVersion();
  else
    return modem->GetAssocFirmwareVersion(type);
}

}  // namespace

ModemFlasher::ModemFlasher(FirmwareDirectory* firmware_directory,
                           Journal* journal,
                           NotificationManager* notification_mgr,
                           Metrics* metrics)
    : firmware_directory_(firmware_directory),
      journal_(journal),
      notification_mgr_(notification_mgr),
      metrics_(metrics) {}

void ModemFlasher::ProcessFailedToPrepareFirmwareFile(
    const base::Location& code_location,
    const std::string& firmware_path,
    brillo::ErrorPtr* err) {
  Error::AddTo(err, code_location, kErrorResultFailedToPrepareFirmwareFile,
               base::StringPrintf("Failed to prepare firmware file: %s",
                                  firmware_path.c_str()));
  notification_mgr_->NotifyUpdateFirmwareCompletedFailure(err->get());
}

uint32_t ModemFlasher::GetFirmwareTypesForMetrics(
    std::vector<FirmwareConfig> flash_cfg) {
  uint32_t fw_types = 0;
  if (flash_cfg.empty())
    return 0;
  for (const auto& info : flash_cfg) {
    std::string fw_type = info.fw_type;
    if (fw_type == kFwMain)
      fw_types |=
          static_cast<int>(metrics::ModemFirmwareType::kModemFirmwareTypeMain);
    else if (fw_type == kFwOem)
      fw_types |=
          static_cast<int>(metrics::ModemFirmwareType::kModemFirmwareTypeOem);
    else if (fw_type == kFwCarrier)
      fw_types |= static_cast<int>(
          metrics::ModemFirmwareType::kModemFirmwareTypeCarrier);
    else if (fw_type == kFwAp)
      fw_types |=
          static_cast<int>(metrics::ModemFirmwareType::kModemFirmwareTypeAp);
    else if (fw_type == kFwDev)
      fw_types |=
          static_cast<int>(metrics::ModemFirmwareType::kModemFirmwareTypeDev);
    else
      fw_types |= static_cast<int>(
          metrics::ModemFirmwareType::kModemFirmwareTypeUnknown);
  }

  ELOG(INFO) << "metrics_fw_types " << fw_types;

  return fw_types;
}

base::OnceClosure ModemFlasher::TryFlash(Modem* modem,
                                         bool modem_seen_since_oobe,
                                         brillo::ErrorPtr* err) {
  std::string equipment_id = modem->GetEquipmentId();
  FlashState* flash_state = &modem_info_[equipment_id];
  if (!flash_state->ShouldFlash()) {
    Error::AddTo(
        err, FROM_HERE, kErrorResultFlashFailure,
        base::StringPrintf("Modem with equipment ID \"%s\" failed to flash too "
                           "many times; not flashing",
                           equipment_id.c_str()));
    notification_mgr_->NotifyUpdateFirmwareCompletedFailure(err->get());
    return base::OnceClosure();
  }

  std::string device_id = modem->GetDeviceId();
  std::string current_carrier = modem->GetCarrierId();
  // The real carrier ID before it might be replaced by the generic one
  std::string real_carrier = current_carrier;
  flash_state->OnCarrierSeen(current_carrier);
  FirmwareDirectory::Files files = firmware_directory_->FindFirmware(
      device_id, current_carrier.empty() ? nullptr : &current_carrier);

  // Clear the attach APN if needed for a specific modem/carrier combination.
  if (!real_carrier.empty() && !modem->ClearAttachAPN(real_carrier))
    ELOG(INFO) << "Clear attach APN failed for current carrier.";

  std::vector<FirmwareConfig> flash_cfg;

  std::vector<std::pair<std::string, const FirmwareFileInfo*>> flash_infos;
  if (files.main_firmware.has_value())
    flash_infos.emplace_back(kFwMain, &files.main_firmware.value());
  if (files.oem_firmware.has_value())
    flash_infos.emplace_back(kFwOem, &files.oem_firmware.value());
  for (const auto& assoc_entry : files.assoc_firmware)
    flash_infos.emplace_back(assoc_entry.first, &assoc_entry.second);

  std::map<std::string, std::unique_ptr<FirmwareFile>> flash_files;
  for (const auto& flash_info : flash_infos) {
    const FirmwareFileInfo& file_info = *flash_info.second;
    base::FilePath fw_path = GetFirmwarePath(file_info);
    if (!flash_state->ShouldFlashFirmware(flash_info.first, fw_path))
      continue;

    std::string existing_version = GetFirmwareVersion(modem, flash_info.first);
    ELOG(INFO) << "Found " << flash_info.first << " firmware blob "
               << file_info.version << ", currently installed "
               << flash_info.first << " firmware version: " << existing_version;
    if (file_info.version == existing_version) {
      // We don't need to check the firmware again if there's nothing new.
      // Pretend that we successfully flashed it.
      flash_state->OnFlashedFirmware(flash_info.first, fw_path);
      continue;
    }

    auto firmware_file = std::make_unique<FirmwareFile>();
    if (!firmware_file->PrepareFrom(firmware_directory_->GetFirmwarePath(),
                                    file_info)) {
      ProcessFailedToPrepareFirmwareFile(FROM_HERE, file_info.firmware_path,
                                         err);
      return base::OnceClosure();
    }

    // We found different firmware! Add it to the list of firmware to flash.
    flash_cfg.push_back({flash_info.first, firmware_file->path_on_filesystem(),
                         file_info.version});
    flash_files[flash_info.first] = std::move(firmware_file);
  }

  // Check if we need to update the carrier firmware.
  if (!current_carrier.empty() && files.carrier_firmware.has_value() &&
      flash_state->ShouldFlashFirmware(
          kFwCarrier, GetFirmwarePath(files.carrier_firmware.value()))) {
    const FirmwareFileInfo& file_info = files.carrier_firmware.value();

    ELOG(INFO) << "Found carrier firmware blob " << file_info.version
               << " for carrier " << current_carrier;

    // Carrier firmware operates a bit differently. We need to flash if
    // the carrier or the version has changed, or if there wasn't any carrier
    // firmware to begin with.
    std::string carrier_fw_id = modem->GetCarrierFirmwareId();
    std::string carrier_fw_version = modem->GetCarrierFirmwareVersion();
    bool has_carrier_fw =
        !(carrier_fw_id.empty() || carrier_fw_version.empty());
    if (has_carrier_fw) {
      ELOG(INFO) << "Currently installed carrier firmware version "
                 << carrier_fw_version << " for carrier " << carrier_fw_id;
    } else {
      ELOG(INFO) << "No carrier firmware is currently installed";
    }

    if (!has_carrier_fw ||
        !firmware_directory_->IsUsingSameFirmware(device_id, carrier_fw_id,
                                                  current_carrier) ||
        carrier_fw_version != file_info.version) {
      auto firmware_file = std::make_unique<FirmwareFile>();
      if (!firmware_file->PrepareFrom(firmware_directory_->GetFirmwarePath(),
                                      file_info)) {
        ProcessFailedToPrepareFirmwareFile(FROM_HERE, file_info.firmware_path,
                                           err);
        return base::OnceClosure();
      }

      flash_cfg.push_back(
          {kFwCarrier, firmware_file->path_on_filesystem(), file_info.version});
      flash_files[kFwCarrier] = std::move(firmware_file);
    }
  } else {
    // Log why we are not flashing the carrier firmware for debug
    if (current_carrier.empty()) {
      ELOG(INFO) << "No carrier found. Is a SIM card inserted?";
    } else if (!files.carrier_firmware.has_value()) {
      // Check if we have carrier firmware matching the SIM's carrier. If not,
      // there's nothing to flash.
      ELOG(INFO) << "No carrier firmware found for carrier " << current_carrier;
    } else {
      // ShouldFlashCarrierFirmware() was false
      ELOG(INFO) << "Already flashed carrier firmware for " << current_carrier;
    }
  }

  // Flash if we have new firmwares
  if (flash_cfg.empty()) {
    // This message is used by tests to track the end of flashing.
    LOG(INFO) << "The modem already has the correct firmware installed";
    notification_mgr_->NotifyUpdateFirmwareCompletedSuccess(false, 0);
    return base::OnceClosure();
  }
  std::vector<std::string> fw_types;
  std::transform(flash_cfg.begin(), flash_cfg.end(),
                 std::back_inserter(fw_types),
                 [](const FirmwareConfig& cfg) { return cfg.fw_type; });

  InhibitMode _inhibit(modem);
  journal_->MarkStartOfFlashingFirmware(fw_types, device_id, current_carrier);

  base::Time start_time = base::Time::Now();
  if (!modem->FlashFirmwares(flash_cfg)) {
    flash_state->OnFlashFailed();
    journal_->MarkEndOfFlashingFirmware(device_id, current_carrier);
    Error::AddTo(err, FROM_HERE,
                 (modem_seen_since_oobe
                      ? kErrorResultFailureReturnedByHelper
                      : kErrorResultFailureReturnedByHelperModemNeverSeen),
                 "Helper failed to flash firmware files");
    notification_mgr_->NotifyUpdateFirmwareCompletedFlashFailure(
        err->get(), GetFirmwareTypesForMetrics(flash_cfg));
    return base::OnceClosure();
  }
  // Report flashing time in successful cases
  metrics_->SendFwFlashTime(base::Time::Now() - start_time);

  for (const auto& info : flash_cfg) {
    std::string fw_type = info.fw_type;
    base::FilePath path_for_logging = flash_files[fw_type]->path_for_logging();
    flash_state->OnFlashedFirmware(fw_type, path_for_logging);
    ELOG(INFO) << "Flashed " << fw_type << " firmware (" << path_for_logging
               << ") to the modem";
  }
  return base::BindOnce(&ModemFlasher::FlashFinished, base::Unretained(this),
                        device_id, current_carrier,
                        GetFirmwareTypesForMetrics(flash_cfg));
}

base::FilePath ModemFlasher::GetFirmwarePath(const FirmwareFileInfo& info) {
  return firmware_directory_->GetFirmwarePath().Append(info.firmware_path);
}

void ModemFlasher::FlashFinished(const std::string& device_id,
                                 const std::string& carrier_id,
                                 uint32_t fw_types_flashed) {
  journal_->MarkEndOfFlashingFirmware(device_id, carrier_id);
  notification_mgr_->NotifyUpdateFirmwareCompletedSuccess(true,
                                                          fw_types_flashed);
}

}  // namespace modemfwd
