// 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/firmware_directory.h"

#include <memory>
#include <utility>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/macros.h>
#include <cros_config/cros_config.h>

#include "modemfwd/firmware_manifest.h"
#include "modemfwd/logging.h"

namespace modemfwd {

namespace {

const char kManifestName[] = "firmware_manifest.prototxt";

// Returns the modem firmware variant for the current model of the device by
// reading the /modem/firmware-variant property of the current model via
// chromeos-config. Returns an empty string if it fails to read the modem
// firmware variant from chromeos-config or no modem firmware variant is
// specified.
std::string GetModemFirmwareVariant() {
  brillo::CrosConfig config;
  if (!config.Init()) {
    LOG(WARNING) << "Failed to load Chrome OS configuration";
    return std::string();
  }

  std::string variant;
  if (!config.GetString("/modem", "firmware-variant", &variant)) {
    LOG(INFO) << "No modem firmware variant is specified";
    return std::string();
  }

  LOG(INFO) << "Use modem firmware variant: " << variant;
  return variant;
}

}  // namespace

const char FirmwareDirectory::kGenericCarrierId[] = "generic";

class FirmwareDirectoryImpl : public FirmwareDirectory {
 public:
  FirmwareDirectoryImpl(FirmwareIndex index, const base::FilePath& directory)
      : index_(std::move(index)),
        directory_(directory),
        variant_(GetModemFirmwareVariant()) {}
  FirmwareDirectoryImpl(const FirmwareDirectoryImpl&) = delete;
  FirmwareDirectoryImpl& operator=(const FirmwareDirectoryImpl&) = delete;

  // modemfwd::FirmwareDirectory overrides.
  FirmwareDirectory::Files FindFirmware(const std::string& device_id,
                                        std::string* carrier_id) override {
    FirmwareDirectory::Files result;

    DeviceType type{device_id, variant_};
    auto device_it = index_.find(type);
    if (device_it == index_.end()) {
      ELOG(INFO) << "Firmware directory has no firmware for device ID ["
                 << device_id << "]";
      return result;
    }

    const DeviceFirmwareCache& cache = device_it->second;
    FirmwareFileInfo info;

    // Null carrier ID -> just go for generic main firmware.
    if (!carrier_id) {
      if (FindSpecificFirmware(cache.main_firmware, kGenericCarrierId, &info))
        result.main_firmware = info;
      return result;
    }

    // Searching for carrier firmware may change the carrier to generic. This
    // is fine, and the main firmware should use the same one in that case.
    if (FindFirmwareForCarrier(cache.carrier_firmware, carrier_id, &info))
      result.carrier_firmware = info;
    if (FindFirmwareForCarrier(cache.main_firmware, carrier_id, &info))
      result.main_firmware = info;

    return result;
  }

  // modemfwd::IsUsingSameFirmware overrides.
  bool IsUsingSameFirmware(const std::string& device_id,
                           const std::string& carrier_a,
                           const std::string& carrier_b) override {
    // easy case: identical carrier UUID
    if (carrier_a == carrier_b)
      return true;

    DeviceType type{device_id, variant_};
    auto device_it = index_.find(type);
    // no firmware for this device
    if (device_it == index_.end())
      return true;

    const DeviceFirmwareCache& cache = device_it->second;
    auto main_a = cache.main_firmware.find(carrier_a);
    auto main_b = cache.main_firmware.find(carrier_b);
    auto cust_a = cache.carrier_firmware.find(carrier_a);
    auto cust_b = cache.carrier_firmware.find(carrier_b);
    // one or several firmwares are missing
    if (main_a == cache.main_firmware.end() ||
        main_b == cache.main_firmware.end() ||
        cust_a == cache.carrier_firmware.end() ||
        cust_b == cache.carrier_firmware.end())
      return main_a == main_b && cust_a == cust_b;
    // same firmware if they are pointing to the 2 same files.
    return main_a->second == main_b->second && cust_a->second == cust_b->second;
  }

 private:
  bool FindFirmwareForCarrier(
      const DeviceFirmwareCache::CarrierIndex& carrier_index,
      std::string* carrier_id,
      FirmwareFileInfo* out_info) {
    if (FindSpecificFirmware(carrier_index, *carrier_id, out_info))
      return true;

    if (FindSpecificFirmware(carrier_index, kGenericCarrierId, out_info)) {
      *carrier_id = kGenericCarrierId;
      return true;
    }

    return false;
  }

  bool FindSpecificFirmware(
      const DeviceFirmwareCache::CarrierIndex& carrier_index,
      const std::string& carrier_id,
      FirmwareFileInfo* out_info) {
    auto it = carrier_index.find(carrier_id);
    if (it == carrier_index.end())
      return false;

    *out_info = *it->second;
    return true;
  }

  FirmwareIndex index_;
  base::FilePath directory_;
  std::string variant_;
};

std::unique_ptr<FirmwareDirectory> CreateFirmwareDirectory(
    const base::FilePath& directory) {
  FirmwareIndex index;
  if (!ParseFirmwareManifestV2(directory.Append(kManifestName), &index)) {
    LOG(INFO) << "Firmware manifest did not parse as V2, falling back to V1";
    if (!ParseFirmwareManifest(directory.Append(kManifestName), &index))
      return nullptr;
  }

  return std::make_unique<FirmwareDirectoryImpl>(std::move(index), directory);
}

}  // namespace modemfwd
