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

namespace shill {

namespace {
constexpr int kGetManagedObjectsTimeout = 5000;
}

ModemInfo::ModemInfo(ControlInterface* control_interface,
                     EventDispatcher* dispatcher,
                     Metrics* metrics,
                     Manager* manager)
    : control_interface_(control_interface),
      dispatcher_(dispatcher),
      metrics_(metrics),
      manager_(manager),
      weak_ptr_factory_(this) {}

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

void ModemInfo::Start() {
  LOG(INFO) << "ModemInfo::Start";

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

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

void ModemInfo::Stop() {
  LOG(INFO) << "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) {
  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(INFO) << "Modem " << path.value() << " already exists.";
    return;
  }
  std::unique_ptr<Modem> modem = CreateModem(path, properties);
  modems_[modem->path()] = std::move(modem);
}

void ModemInfo::RemoveModem(const RpcIdentifier& path) {
  LOG(INFO) << "Remove modem: " << path.value();
  CHECK(service_connected_);
  modems_.erase(path);
}

void ModemInfo::OnAppeared() {
  LOG(INFO) << "ModemInfo::OnAppeared";
  Connect();
}

void ModemInfo::OnVanished() {
  LOG(INFO) << "ModemInfo::OnVanished";
  Disconnect();
}

void ModemInfo::OnInterfacesAddedSignal(
    const RpcIdentifier& object_path, const InterfaceToProperties& properties) {
  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) {
  LOG(INFO) << "ModemInfo:  Removing interfaces from: " << 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
