// Copyright 2014 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 "peerd/manager.h"

#include <string>

#include <dbus/bus.h>
#include <dbus/mock_bus.h>
#include <dbus/object_path.h>

#include "peerd/constants.h"
#include "peerd/mock_avahi_client.h"
#include "peerd/mock_peer_manager.h"
#include "peerd/mock_published_peer.h"
#include "peerd/service.h"

using brillo::dbus_utils::DBusObject;
using dbus::MockBus;
using dbus::ObjectPath;
using peerd::constants::kSerbusServiceId;
using std::string;
using std::unique_ptr;
using testing::AnyNumber;
using testing::Mock;
using testing::Return;
using testing::_;

namespace peerd {
namespace {

// Chrome doesn't bother mocking out their objects completely.
class EspeciallyMockedBus : public dbus::MockBus {
 public:
  using dbus::MockBus::MockBus;

  MOCK_METHOD2(GetServiceOwner,
               void(const std::string& service_name,
                    const GetServiceOwnerCallback& callback));

  MOCK_METHOD2(ListenForServiceOwnerChange,
               void(const std::string& service_name,
                    const GetServiceOwnerCallback& callback));

  MOCK_METHOD2(UnlistenForServiceOwnerChange,
               void(const std::string& service_name,
                    const GetServiceOwnerCallback& callback));

 protected:
  virtual ~EspeciallyMockedBus() = default;
};

}  // namespace

class ManagerTest : public testing::Test {
 public:
  void SetUp() override {
    unique_ptr<DBusObject> dbus_object{new DBusObject{
        nullptr,
        mock_bus_,
        ObjectPath{"/manager/object/path"}}};
    // Ignore threading concerns.
    EXPECT_CALL(*mock_bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*mock_bus_, AssertOnDBusThread()).Times(AnyNumber());
    peer_ = new MockPublishedPeer{mock_bus_, ObjectPath{"/peer/prefix"}};
    peer_manager_ = new MockPeerManager();
    avahi_client_ = new MockAvahiClient(mock_bus_, peer_manager_);
    manager_.reset(new Manager{scoped_refptr<dbus::Bus>{mock_bus_.get()},
                               std::move(dbus_object),
                               unique_ptr<PublishedPeer>{peer_},
                               unique_ptr<PeerManagerInterface>{peer_manager_},
                               unique_ptr<AvahiClient>{avahi_client_},
                               ""});
  }

  std::vector<string> GetMonitoredTechnologies() {
    return manager_->dbus_adaptor_.GetMonitoredTechnologies();
  }

  const std::map<std::string, brillo::Any> kNoOptions;
  const std::vector<std::string> kOnlyMdns{technologies::kMDNSText};
  scoped_refptr<EspeciallyMockedBus>
      mock_bus_{new EspeciallyMockedBus{dbus::Bus::Options{}}};
  unique_ptr<Manager> manager_;
  MockPublishedPeer* peer_;  // manager_ owns this object.
  MockPeerManager* peer_manager_;  // manager_ owns this object.
  MockAvahiClient* avahi_client_;  // manager_ owns this object.
};

TEST_F(ManagerTest, ShouldRejectSerbusServiceId) {
  brillo::ErrorPtr error;
  dbus::MethodCall method_call{"org.chromium.peerd.Manager", "ExposeService"};
  EXPECT_FALSE(manager_->ExposeService(
      &error, &method_call, kSerbusServiceId, {}, {}));
  EXPECT_NE(nullptr, error.get());
}

TEST_F(ManagerTest, StartMonitoring_ShouldRejectEmptyTechnologies) {
  brillo::ErrorPtr error;
  string token;
  EXPECT_FALSE(manager_->StartMonitoring(&error, {}, kNoOptions, &token));
  EXPECT_NE(nullptr, error.get());
}

TEST_F(ManagerTest, StartMonitoring_ShouldRejectInvalidTechnologies) {
  brillo::ErrorPtr error;
  string token;
  EXPECT_FALSE(manager_->StartMonitoring(
      &error, {"hot air balloon"}, kNoOptions, &token));
  EXPECT_NE(nullptr, error.get());
  EXPECT_EQ(GetMonitoredTechnologies(), std::vector<string>{});
}

TEST_F(ManagerTest, StartMonitoring_ShouldAcceptMDNS) {
  brillo::ErrorPtr error;
  EXPECT_CALL(*avahi_client_, StartMonitoring());
  string token;
  EXPECT_TRUE(manager_->StartMonitoring(
      &error, {technologies::kMDNSText}, kNoOptions, &token));
  EXPECT_TRUE(!token.empty());
  EXPECT_EQ(nullptr, error.get());
  EXPECT_EQ(GetMonitoredTechnologies(), kOnlyMdns);
}

TEST_F(ManagerTest, StopMonitoring_HandlesInvalidToken) {
  brillo::ErrorPtr error;
  EXPECT_FALSE(manager_->StopMonitoring(&error, "invalid_token"));
  EXPECT_NE(nullptr, error.get());
}

TEST_F(ManagerTest, StopMonitoring_HandlesSingleSubscription) {
  brillo::ErrorPtr error;
  EXPECT_CALL(*avahi_client_, StartMonitoring());
  string token;
  EXPECT_TRUE(manager_->StartMonitoring(
      &error, {technologies::kMDNSText}, kNoOptions, &token));
  EXPECT_TRUE(!token.empty());
  EXPECT_EQ(nullptr, error.get());
  EXPECT_CALL(*avahi_client_, StopMonitoring());
  manager_->StopMonitoring(&error, token);
  EXPECT_FALSE(error.get());
  // Unsubscribing a second time is invalid.
  manager_->StopMonitoring(&error, token);
  EXPECT_NE(nullptr, error.get());
}

TEST_F(ManagerTest, StopMonitoring_HandlesMultipleSubscriptions) {
  brillo::ErrorPtr error;
  // We don't bother to figure out if we're already monitoring on a technology.
  EXPECT_CALL(*avahi_client_, StartMonitoring()).Times(2);
  string token1;
  string token2;
  EXPECT_TRUE(manager_->StartMonitoring(
      &error, {technologies::kMDNSText}, kNoOptions, &token1));
  EXPECT_TRUE(manager_->StartMonitoring(
      &error, {technologies::kMDNSText}, kNoOptions, &token2));
  EXPECT_TRUE(!token1.empty());
  EXPECT_TRUE(!token2.empty());
  EXPECT_EQ(nullptr, error.get());
  EXPECT_EQ(GetMonitoredTechnologies(), kOnlyMdns);
  Mock::VerifyAndClearExpectations(avahi_client_);
  // Now, remove one subscription, we should keep monitoring.
  EXPECT_CALL(*avahi_client_, StopMonitoring()).Times(0);
  manager_->StopMonitoring(&error, token1);
  EXPECT_EQ(nullptr, error.get());
  Mock::VerifyAndClearExpectations(avahi_client_);
  EXPECT_CALL(*avahi_client_, StopMonitoring());
  manager_->StopMonitoring(&error, token2);
}

TEST_F(ManagerTest, ShouldRemoveServicesOnRemoteDeath) {
  const string kServiceId{"a_service_id"};
  const string kDBusSender{"a.dbus.connection.id"};
  EXPECT_CALL(*peer_, AddPublishedService(_, kServiceId, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*mock_bus_, ListenForServiceOwnerChange(kDBusSender, _));
  EXPECT_CALL(*mock_bus_, GetServiceOwner(kDBusSender, _));
  dbus::MethodCall method_call{"org.chromium.peerd.Manager", "ExposeService"};
  method_call.SetSender(kDBusSender);
  EXPECT_TRUE(manager_->ExposeService(
      nullptr, &method_call, kServiceId, {}, {}));
  Mock::VerifyAndClearExpectations(peer_);
  Mock::VerifyAndClearExpectations(mock_bus_.get());
  EXPECT_CALL(*peer_, RemoveService(_, kServiceId));
  EXPECT_CALL(*mock_bus_, UnlistenForServiceOwnerChange(kDBusSender, _));
  manager_->OnDBusServiceDeath(kServiceId);
}

}  // namespace peerd
