// 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 <ModemManager/ModemManager.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "shill/cellular/mock_dbus_objectmanager_proxy.h"
#include "shill/cellular/modem.h"
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/test_event_dispatcher.h"

#include <base/check.h>

using testing::_;
using testing::SaveArg;
using testing::Test;

namespace shill {

namespace {
const RpcIdentifier kModemPath =
    RpcIdentifier("/org/freedesktop/ModemManager1/Modem/0");
}

class ModemInfoForTest : public ModemInfo {
 public:
  ModemInfoForTest(ControlInterface* control, Manager* manager)
      : ModemInfo(control, manager) {
    // See note for |mock_proxy_|.
    mock_proxy_ = std::make_unique<MockDBusObjectManagerProxy>();
    mock_proxy_->IgnoreSetCallbacks();
  }

  std::unique_ptr<DBusObjectManagerProxyInterface> CreateProxy() override {
    return std::move(mock_proxy_);
  }

  std::unique_ptr<Modem> CreateModem(
      const RpcIdentifier& path,
      const InterfaceToProperties& properties) override {
    return std::make_unique<Modem>(modemmanager::kModemManager1ServiceName,
                                   path, this);
  }

  MockDBusObjectManagerProxy* GetMockProxy() {
    CHECK(mock_proxy_);
    return mock_proxy_.get();
  }

 private:
  // Note: Ownership will be relenquished when CreateProxy() is called.
  std::unique_ptr<MockDBusObjectManagerProxy> mock_proxy_;
};

class ModemInfoTest : public Test {
 public:
  ModemInfoTest()
      : manager_(&control_interface_, &dispatcher_, &metrics_),
        modem_info_(&control_interface_, &manager_) {}

 protected:
  void Connect(const ObjectsWithProperties& expected_objects) {
    ManagedObjectsCallback get_managed_objects_callback;
    EXPECT_CALL(*modem_info_.GetMockProxy(), GetManagedObjects(_, _, _))
        .WillOnce(SaveArg<1>(&get_managed_objects_callback));

    modem_info_.Start();
    modem_info_.Connect();
    get_managed_objects_callback.Run(expected_objects, Error());
  }

  ObjectsWithProperties GetModemWithProperties() {
    KeyValueStore o_fd_mm1_modem;

    InterfaceToProperties properties;
    properties[MM_DBUS_INTERFACE_MODEM] = o_fd_mm1_modem;

    ObjectsWithProperties objects_with_properties;
    objects_with_properties[kModemPath] = properties;

    return objects_with_properties;
  }

  MockControl control_interface_;
  EventDispatcherForTest dispatcher_;
  MockMetrics metrics_;
  MockManager manager_;
  ModemInfoForTest modem_info_;
};

TEST_F(ModemInfoTest, ConnectDisconnect) {
  modem_info_.Start();
  EXPECT_FALSE(modem_info_.service_connected_);

  modem_info_.Connect();
  EXPECT_TRUE(modem_info_.service_connected_);
  EXPECT_EQ(0, modem_info_.modems_.size());

  modem_info_.AddModem(kModemPath, InterfaceToProperties());
  EXPECT_EQ(1, modem_info_.modems_.size());

  modem_info_.Disconnect();
  EXPECT_FALSE(modem_info_.service_connected_);
  EXPECT_EQ(0, modem_info_.modems_.size());
}

TEST_F(ModemInfoTest, AddRemoveModem) {
  modem_info_.Start();
  modem_info_.Connect();
  EXPECT_FALSE(modem_info_.ModemExists(kModemPath));

  // Remove non-existent modem path.
  modem_info_.RemoveModem(kModemPath);
  EXPECT_FALSE(modem_info_.ModemExists(kModemPath));

  modem_info_.AddModem(kModemPath, InterfaceToProperties());
  EXPECT_TRUE(modem_info_.ModemExists(kModemPath));

  // Add an already added modem.
  modem_info_.AddModem(kModemPath, InterfaceToProperties());
  EXPECT_TRUE(modem_info_.ModemExists(kModemPath));

  modem_info_.RemoveModem(kModemPath);
  EXPECT_FALSE(modem_info_.ModemExists(kModemPath));

  // Remove an already removed modem path.
  modem_info_.RemoveModem(kModemPath);
  EXPECT_FALSE(modem_info_.ModemExists(kModemPath));
}

TEST_F(ModemInfoTest, StartStop) {
  modem_info_.Start();
  EXPECT_NE(nullptr, modem_info_.proxy_);

  modem_info_.Stop();
  EXPECT_EQ(nullptr, modem_info_.proxy_);
}

TEST_F(ModemInfoTest, Connect) {
  Connect(GetModemWithProperties());
  EXPECT_EQ(1, modem_info_.modems_.size());
  EXPECT_TRUE(base::Contains(modem_info_.modems_, kModemPath));
}

TEST_F(ModemInfoTest, AddRemoveInterfaces) {
  // Have nothing come back from GetManagedObjects.
  Connect(ObjectsWithProperties());
  EXPECT_EQ(0, modem_info_.modems_.size());

  // Add an object that doesn't have a modem interface.  Nothing should be added
  modem_info_.OnInterfacesAddedSignal(kModemPath, InterfaceToProperties());
  EXPECT_EQ(0, modem_info_.modems_.size());

  // Actually add a modem
  modem_info_.OnInterfacesAddedSignal(kModemPath,
                                      GetModemWithProperties()[kModemPath]);
  EXPECT_EQ(1, modem_info_.modems_.size());

  // Remove an irrelevant interface
  modem_info_.OnInterfacesRemovedSignal(kModemPath, {"not.a.modem.interface"});
  EXPECT_EQ(1, modem_info_.modems_.size());

  // Remove the modem
  modem_info_.OnInterfacesRemovedSignal(kModemPath, {MM_DBUS_INTERFACE_MODEM});
  EXPECT_EQ(0, modem_info_.modems_.size());
}

}  // namespace shill
