// Copyright 2018 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 "shill/cellular/modem_info.h"

#include <memory>
#include <utility>

#include <chromeos/dbus/service_constants.h>
#include <ModemManager/ModemManager.h>

#include "shill/cellular/dbus_objectmanager_proxy_interface.h"
#include "shill/cellular/modem.h"
#include "shill/cellular/pending_activation_store.h"
#include "shill/control_interface.h"
#include "shill/dbus/dbus_objectmanager_proxy.h"
#include "shill/logging.h"
#include "shill/manager.h"

#include <base/check.h>

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kModem;
static std::string ObjectID(const ModemInfo* m) {
  return "(modem info)";
}
}  // namespace Logging

namespace {
constexpr int kGetManagedObjectsTimeout = 5000;
}

ModemInfo::ModemInfo(ControlInterface* control_interface, Manager* manager)
    : control_interface_(control_interface),
      manager_(manager),
      weak_ptr_factory_(this) {}

ModemInfo::~ModemInfo() {
  Stop();
}

void ModemInfo::Start() {
  SLOG(this, 1) << "ModemInfo::Start";

  pending_activation_store_.reset(new PendingActivationStore());
  pending_activation_store_->InitStorage(manager_->storage_path());

  CHECK(!proxy_);
  proxy_ = CreateProxy();
}

void ModemInfo::Stop() {
  SLOG(this, 1) << "ModemInfo::Stop";
  pending_activation_store_.reset();
  proxy_.reset();
  Disconnect();
}

void ModemInfo::OnDeviceInfoAvailable(const std::string& link_name) {
  for (const auto& modem_entry : modems_) {
    modem_entry.second->OnDeviceInfoAvailable(link_name);
  }
}

std::unique_ptr<DBusObjectManagerProxyInterface> ModemInfo::CreateProxy() {
  std::unique_ptr<DBusObjectManagerProxyInterface> proxy =
      control_interface_->CreateDBusObjectManagerProxy(
          RpcIdentifier(modemmanager::kModemManager1ServicePath),
          modemmanager::kModemManager1ServiceName,
          base::Bind(&ModemInfo::OnAppeared, weak_ptr_factory_.GetWeakPtr()),
          base::Bind(&ModemInfo::OnVanished, weak_ptr_factory_.GetWeakPtr()));
  proxy->set_interfaces_added_callback(Bind(&ModemInfo::OnInterfacesAddedSignal,
                                            weak_ptr_factory_.GetWeakPtr()));
  proxy->set_interfaces_removed_callback(Bind(
      &ModemInfo::OnInterfacesRemovedSignal, weak_ptr_factory_.GetWeakPtr()));
  return proxy;
}

std::unique_ptr<Modem> ModemInfo::CreateModem(
    const RpcIdentifier& path, const InterfaceToProperties& properties) {
  SLOG(this, 1) << __func__ << ": " << path.value();
  auto modem = std::make_unique<Modem>(modemmanager::kModemManager1ServiceName,
                                       path, this);
  modem->CreateDeviceMM1(properties);
  return modem;
}

void ModemInfo::Connect() {
  service_connected_ = true;
  Error error;
  CHECK(proxy_);
  proxy_->GetManagedObjects(&error,
                            Bind(&ModemInfo::OnGetManagedObjectsReply,
                                 weak_ptr_factory_.GetWeakPtr()),
                            kGetManagedObjectsTimeout);
}

void ModemInfo::Disconnect() {
  modems_.clear();
  service_connected_ = false;
}

bool ModemInfo::ModemExists(const RpcIdentifier& path) const {
  CHECK(service_connected_);
  return base::Contains(modems_, path);
}

void ModemInfo::AddModem(const RpcIdentifier& path,
                         const InterfaceToProperties& properties) {
  if (ModemExists(path)) {
    LOG(WARNING) << "Modem " << path.value() << " already exists.";
    return;
  }
  SLOG(this, 1) << __func__ << ": " << path.value();
  std::unique_ptr<Modem> modem = CreateModem(path, properties);
  modems_[modem->path()] = std::move(modem);
}

void ModemInfo::RemoveModem(const RpcIdentifier& path) {
  SLOG(this, 1) << __func__ << ": " << path.value();
  CHECK(service_connected_);
  modems_.erase(path);
}

void ModemInfo::OnAppeared() {
  SLOG(this, 1) << __func__;
  Connect();
}

void ModemInfo::OnVanished() {
  SLOG(this, 1) << __func__;
  Disconnect();
}

void ModemInfo::OnInterfacesAddedSignal(
    const RpcIdentifier& object_path, const InterfaceToProperties& properties) {
  SLOG(this, 2) << __func__ << ": " << object_path.value();
  if (!base::Contains(properties, MM_DBUS_INTERFACE_MODEM)) {
    LOG(ERROR) << "Interfaces added, but not modem interface.";
    return;
  }
  AddModem(object_path, properties);
}

void ModemInfo::OnInterfacesRemovedSignal(
    const RpcIdentifier& object_path,
    const std::vector<std::string>& interfaces) {
  SLOG(this, 2) << __func__ << ": " << object_path.value();
  if (!base::Contains(interfaces, MM_DBUS_INTERFACE_MODEM)) {
    // In theory, a modem could drop, say, 3GPP, but not CDMA.  In
    // practice, we don't expect this.
    LOG(ERROR) << "Interfaces removed, but not modem interface";
    return;
  }
  RemoveModem(object_path);
}

void ModemInfo::OnGetManagedObjectsReply(const ObjectsWithProperties& objects,
                                         const Error& error) {
  if (!error.IsSuccess())
    return;
  for (const auto& object_properties_pair : objects) {
    OnInterfacesAddedSignal(object_properties_pair.first,
                            object_properties_pair.second);
  }
}

}  // namespace shill
