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

#include <map>
#include <utility>

#include <base/check.h>

namespace {

template <typename Map, typename K, typename V>
bool GetValue(const Map& map, const K& key, V* out_value) {
  CHECK(out_value);

  auto it = map.find(key);
  if (it == map.end())
    return false;

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

}  // namespace

namespace modemfwd {

void FirmwareDirectoryStub::AddMainFirmware(const std::string& device_id,
                                            FirmwareFileInfo info) {
  main_fw_info_.insert(std::make_pair(device_id, info));
}

void FirmwareDirectoryStub::AddMainFirmwareForCarrier(
    const std::string& device_id,
    const std::string& carrier_id,
    FirmwareFileInfo info) {
  main_fw_info_for_carrier_.insert(
      std::make_pair(std::make_pair(device_id, carrier_id), info));
}

void FirmwareDirectoryStub::AddOemFirmware(const std::string& device_id,
                                           FirmwareFileInfo info) {
  oem_fw_info_.insert(std::make_pair(device_id, info));
}

void FirmwareDirectoryStub::AddOemFirmwareForCarrier(
    const std::string& device_id,
    const std::string& carrier_id,
    FirmwareFileInfo info) {
  oem_fw_info_for_carrier_.insert(
      std::make_pair(std::make_pair(device_id, carrier_id), info));
}

void FirmwareDirectoryStub::AddCarrierFirmware(const std::string& device_id,
                                               const std::string& carrier_id,
                                               FirmwareFileInfo info) {
  carrier_fw_info_.insert(
      std::make_pair(std::make_pair(device_id, carrier_id), info));
}

FirmwareDirectory::Files FirmwareDirectoryStub::FindFirmware(
    const std::string& device_id, std::string* carrier_id) {
  FirmwareDirectory::Files res;
  FirmwareFileInfo info;

  if (carrier_id) {
    if (FindCarrierFirmware(device_id, carrier_id, &info))
      res.carrier_firmware = info;
    if (GetValue(main_fw_info_for_carrier_,
                 std::make_pair(device_id, *carrier_id), &info)) {
      res.main_firmware = info;
    }
    if (GetValue(oem_fw_info_for_carrier_,
                 std::make_pair(device_id, *carrier_id), &info)) {
      res.oem_firmware = info;
    }
  }

  if (!res.oem_firmware.has_value() &&
      GetValue(oem_fw_info_, device_id, &info)) {
    res.oem_firmware = info;
  }

  if (!res.main_firmware.has_value() &&
      GetValue(main_fw_info_, device_id, &info)) {
    res.main_firmware = info;
  }

  return res;
}

bool FirmwareDirectoryStub::FindCarrierFirmware(const std::string& device_id,
                                                std::string* carrier_id,
                                                FirmwareFileInfo* out_info) {
  CHECK(carrier_id);
  if (GetValue(carrier_fw_info_, std::make_pair(device_id, *carrier_id),
               out_info)) {
    return true;
  }

  if (GetValue(carrier_fw_info_, std::make_pair(device_id, kGenericCarrierId),
               out_info)) {
    *carrier_id = kGenericCarrierId;
    return true;
  }

  return false;
}

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

  FirmwareFileInfo info_a;
  FirmwareFileInfo info_b;
  bool has_a =
      GetValue(carrier_fw_info_, std::make_pair(device_id, carrier_a), &info_a);
  bool has_b =
      GetValue(carrier_fw_info_, std::make_pair(device_id, carrier_b), &info_b);
  // one or several firmwares are missing
  if (!has_a || !has_b)
    return false;

  // same firmware if they are pointing to the 2 same files.
  return info_a.firmware_path == info_b.firmware_path;
}

}  // namespace modemfwd
