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

#include <map>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/memory/ptr_util.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/unguessable_token.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <chromeos/dbus/service_constants.h>
#include <ModemManager/ModemManager.h>

#include "modemfwd/logging.h"
#include "modemfwd/modem_helper.h"
#include "modemmanager/dbus-proxies.h"

namespace {

class Inhibitor {
 public:
  Inhibitor(std::unique_ptr<org::freedesktop::ModemManager1Proxy> mm_proxy,
            const std::string& physdev_uid)
      : mm_proxy_(std::move(mm_proxy)), physdev_uid_(physdev_uid) {}

  bool SetInhibited(bool inhibited) {
    brillo::ErrorPtr error_unused;
    return mm_proxy_->InhibitDevice(physdev_uid_, inhibited, &error_unused);
  }

 private:
  std::unique_ptr<org::freedesktop::ModemManager1Proxy> mm_proxy_;
  std::string physdev_uid_;
};

std::unique_ptr<Inhibitor> GetInhibitor(
    scoped_refptr<dbus::Bus> bus, const dbus::ObjectPath& mm_object_path) {
  // Get the MM object backing this modem, and retrieve its Device property.
  // This is the mm_physdev_uid we use for inhibition during updates.
  auto mm_device = bus->GetObjectProxy(modemmanager::kModemManager1ServiceName,
                                       mm_object_path);
  if (!mm_device)
    return nullptr;

  brillo::ErrorPtr error;
  auto resp = brillo::dbus_utils::CallMethodAndBlock(
      mm_device, dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
      &error, std::string(modemmanager::kModemManager1ModemInterface),
      std::string(MM_MODEM_PROPERTY_DEVICE));
  if (!resp)
    return nullptr;

  std::string mm_physdev_uid;
  if (!brillo::dbus_utils::ExtractMethodCallResults(resp.get(), &error,
                                                    &mm_physdev_uid)) {
    return nullptr;
  }

  EVLOG(1) << "Modem " << mm_object_path.value() << " has physdev UID "
           << mm_physdev_uid;
  auto mm_proxy = std::make_unique<org::freedesktop::ModemManager1Proxy>(
      bus, modemmanager::kModemManager1ServiceName);
  return std::make_unique<Inhibitor>(std::move(mm_proxy), mm_physdev_uid);
}

}  // namespace

namespace modemfwd {

class ModemImpl : public Modem {
 public:
  ModemImpl(const std::string& device_id,
            const std::string& equipment_id,
            const std::string& carrier_id,
            std::unique_ptr<Inhibitor> inhibitor,
            ModemHelper* helper)
      : device_id_(device_id),
        equipment_id_(equipment_id),
        carrier_id_(carrier_id),
        inhibitor_(std::move(inhibitor)),
        helper_(helper) {
    if (!helper->GetFirmwareInfo(&installed_firmware_))
      LOG(WARNING) << "Could not fetch installed firmware information";
  }
  ModemImpl(const ModemImpl&) = delete;
  ModemImpl& operator=(const ModemImpl&) = delete;

  ~ModemImpl() override = default;

  // modemfwd::Modem overrides.
  std::string GetDeviceId() const override { return device_id_; }

  std::string GetEquipmentId() const override { return equipment_id_; }

  std::string GetCarrierId() const override { return carrier_id_; }

  std::string GetMainFirmwareVersion() const override {
    return installed_firmware_.main_version;
  }

  std::string GetCarrierFirmwareId() const override {
    return installed_firmware_.carrier_uuid;
  }

  std::string GetCarrierFirmwareVersion() const override {
    return installed_firmware_.carrier_version;
  }

  bool SetInhibited(bool inhibited) override {
    if (!inhibitor_) {
      EVLOG(1) << "Inhibiting unavailable on this modem";
      return false;
    }
    return inhibitor_->SetInhibited(inhibited);
  }

  bool FlashMainFirmware(const base::FilePath& path_to_fw,
                         const std::string& version) override {
    return helper_->FlashMainFirmware(path_to_fw, version);
  }

  bool FlashCarrierFirmware(const base::FilePath& path_to_fw,
                            const std::string& version) override {
    return helper_->FlashCarrierFirmware(path_to_fw, version);
  }

  bool ClearAttachAPN(const std::string& carrier_uuid) override {
    return helper_->ClearAttachAPN(carrier_uuid);
  }

 private:
  std::string device_id_;
  std::string equipment_id_;
  std::string carrier_id_;
  std::unique_ptr<Inhibitor> inhibitor_;
  FirmwareInfo installed_firmware_;
  ModemHelper* helper_;
};

std::unique_ptr<Modem> CreateModem(
    scoped_refptr<dbus::Bus> bus,
    std::unique_ptr<org::chromium::flimflam::DeviceProxy> device,
    ModemHelperDirectory* helper_directory) {
  std::string object_path = device->GetObjectPath().value();
  DVLOG(1) << "Creating modem proxy for " << object_path;

  brillo::ErrorPtr error;
  brillo::VariantDictionary properties;
  if (!device->GetProperties(&properties, &error)) {
    LOG(WARNING) << "Could not get properties for modem " << object_path;
    return nullptr;
  }

  // If we don't have a device ID, modemfwd can't do anything with this modem,
  // so check it first and just return if we can't find it.
  std::string device_id;
  if (!properties[shill::kDeviceIdProperty].GetValue(&device_id)) {
    LOG(INFO) << "Modem " << object_path << " has no device ID, ignoring";
    return nullptr;
  }

  // Equipment ID is also pretty important since we use it as a stable
  // identifier that can distinguish between modems of the same type.
  std::string equipment_id;
  if (!properties[shill::kEquipmentIdProperty].GetValue(&equipment_id)) {
    LOG(INFO) << "Modem " << object_path << " has no equipment ID, ignoring";
    return nullptr;
  }

  // This property may not exist and it's not a big deal if it doesn't.
  std::map<std::string, std::string> operator_info;
  std::string carrier_id;
  if (properties[shill::kHomeProviderProperty].GetValue(&operator_info))
    carrier_id = operator_info[shill::kOperatorUuidKey];

  // Get a helper object for inhibiting the modem, if possible.
  std::unique_ptr<Inhibitor> inhibitor;
  std::string mm_object_path;
  if (!properties[shill::kDBusObjectProperty].GetValue(&mm_object_path)) {
    LOG(INFO) << "Modem " << object_path << " has no ModemManager object";
  } else {
    inhibitor = GetInhibitor(bus, dbus::ObjectPath(mm_object_path));
  }
  if (!inhibitor)
    LOG(INFO) << "Inhibiting modem " << object_path << " will not be possible";

  // Use the device ID to grab a helper.
  ModemHelper* helper = helper_directory->GetHelperForDeviceId(device_id);
  if (!helper) {
    LOG(INFO) << "No helper found to update modems with ID [" << device_id
              << "]";
    return nullptr;
  }

  return std::make_unique<ModemImpl>(device_id, equipment_id, carrier_id,
                                     std::move(inhibitor), helper);
}

// StubModem acts like a modem with a particular device ID but does not
// actually talk to a real modem. This allows us to use it for force-
// flashing.
class StubModem : public Modem {
 public:
  StubModem(const std::string& device_id, ModemHelper* helper)
      : device_id_(device_id),
        equipment_id_(base::UnguessableToken().ToString()),
        helper_(helper) {}
  StubModem(const StubModem&) = delete;
  StubModem& operator=(const StubModem&) = delete;

  ~StubModem() override = default;

  // modemfwd::Modem overrides.
  std::string GetDeviceId() const override { return device_id_; }

  std::string GetEquipmentId() const override { return equipment_id_; }

  std::string GetCarrierId() const override { return ""; }

  std::string GetMainFirmwareVersion() const override { return ""; }

  std::string GetCarrierFirmwareId() const override { return ""; }

  std::string GetCarrierFirmwareVersion() const override { return ""; }

  bool SetInhibited(bool inhibited) override { return true; }

  bool FlashMainFirmware(const base::FilePath& path_to_fw,
                         const std::string& version) override {
    return helper_->FlashMainFirmware(path_to_fw, version);
  }

  bool FlashCarrierFirmware(const base::FilePath& path_to_fw,
                            const std::string& version) override {
    return helper_->FlashCarrierFirmware(path_to_fw, version);
  }

  bool ClearAttachAPN(const std::string& carrier_uuid) override {
    return helper_->ClearAttachAPN(carrier_uuid);
  }

 private:
  std::string device_id_;
  std::string equipment_id_;
  ModemHelper* helper_;
};

std::unique_ptr<Modem> CreateStubModem(const std::string& device_id,
                                       ModemHelperDirectory* helper_directory) {
  // Use the device ID to grab a helper.
  ModemHelper* helper = helper_directory->GetHelperForDeviceId(device_id);
  if (!helper) {
    LOG(INFO) << "No helper found to update modems with ID [" << device_id
              << "]";
    return nullptr;
  }

  return std::make_unique<StubModem>(device_id, helper);
}

}  // namespace modemfwd
