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

#include <string>

#include <chromeos/errors/error.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "peerd/constants.h"
#include "peerd/test_util.h"

using IpAddresses = peerd::Service::IpAddresses;
using ServiceInfo = peerd::Service::ServiceInfo;
using chromeos::Any;
using dbus::Bus;
using dbus::MockBus;
using dbus::MockExportedObject;
using dbus::ObjectPath;
using peerd::constants::options::service::kMDNSPort;
using peerd::constants::options::service::kMDNSSectionName;
using peerd::errors::service::kInvalidServiceId;
using peerd::errors::service::kInvalidServiceInfo;
using peerd::errors::service::kInvalidServiceOptions;
using peerd::test_util::MakeMockCompletionAction;
using std::map;
using std::string;
using std::unique_ptr;
using testing::AnyNumber;
using testing::Invoke;
using testing::Return;
using testing::_;

namespace {

IpAddresses MakeValidIpAddresses() {
  // TODO(wiley) return a non-trivial list here.
  return {};
}

const char kServicePath[] = "/a/path";
const char kValidServiceId[] = "valid-id";

}  // namespace


namespace peerd {

class ServiceTest : public ::testing::Test {
 public:
  void SetUp() override {
    // Ignore threading concerns.
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    // Unless we expect to create a Service object, we won't.
    EXPECT_CALL(*bus_, GetExportedObject(_)).Times(0);
    // Just immediately call callbacks on ExportMethod calls.
    EXPECT_CALL(*service_object_, ExportMethod(_, _, _, _))
        .WillRepeatedly(Invoke(&test_util::HandleMethodExport));
    // Ignore Unregister calls.
    EXPECT_CALL(*service_object_, Unregister()).Times(AnyNumber());
  }

  void AssertMakeServiceFails(const string& service_id,
                              const IpAddresses& addresses,
                              const ServiceInfo& service_info,
                              const map<string, Any>& options,
                              const string& error_code) {
    chromeos::ErrorPtr error;
    EXPECT_FALSE(service_.RegisterAsync(
          &error, service_id, addresses, service_info, options,
          MakeMockCompletionAction()));
    ASSERT_NE(nullptr, error.get());
    EXPECT_TRUE(error->HasError(kPeerdErrorDomain, error_code));
  }

  void AssertMakeServiceSuccess(
      const string& service_id,
      const IpAddresses& addresses,
      const ServiceInfo& service_info,
      const map<string, Any>& options) {
    chromeos::ErrorPtr error;
    EXPECT_CALL(*bus_, GetExportedObject(_))
        .WillOnce(Return(service_object_.get()));
    EXPECT_TRUE(service_.RegisterAsync(
          &error, service_id, addresses, service_info, options,
          MakeMockCompletionAction()));
    EXPECT_EQ(nullptr, error.get());
  }

  scoped_refptr<MockBus> bus_{new MockBus{Bus::Options{}}};
  scoped_refptr<dbus::MockExportedObject> service_object_{
      new MockExportedObject{bus_.get(), ObjectPath{kServicePath}}};
  Service service_{bus_, nullptr, ObjectPath{kServicePath}};
};

TEST_F(ServiceTest, ShouldRejectZeroLengthServiceId) {
  AssertMakeServiceFails("",
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectLongServiceId) {
  AssertMakeServiceFails(string(Service::kMaxServiceIdLength + 1, 'a'),
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectInvalidCharInServiceId) {
  AssertMakeServiceFails("not*allowed",
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectHyphenPrefix) {
  AssertMakeServiceFails("-not-allowed",
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectHyphenSuffix) {
  AssertMakeServiceFails("not-allowed-",
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectAdjacentHyphens) {
  AssertMakeServiceFails("not--allowed",
                         MakeValidIpAddresses(),
                         ServiceInfo(),
                         {},
                         kInvalidServiceId);
}

TEST_F(ServiceTest, ShouldRejectInvalidCharInServiceInfoKey) {
  const ServiceInfo info = {{"spaces are illegal", "valid value"}};
  AssertMakeServiceFails(kValidServiceId,
                         MakeValidIpAddresses(),
                         info,
                         {},
                         kInvalidServiceInfo);
}

TEST_F(ServiceTest, ShouldRejectServiceInfoPairTooLong) {
  const ServiceInfo info = {
      {"k", string(Service::kMaxServiceInfoPairLength, 'v')},
  };
  AssertMakeServiceFails(kValidServiceId,
                         MakeValidIpAddresses(),
                         info,
                         {},
                         kInvalidServiceInfo);
}

TEST_F(ServiceTest, RegisterWhenInputIsValid) {
  AssertMakeServiceSuccess(kValidServiceId,
                           MakeValidIpAddresses(),
                           ServiceInfo(),
                           {});
}

TEST_F(ServiceTest, RegisterWhenInputIsValidBoundaryCases) {
  const ServiceInfo service_info = {
      {"a", string(Service::kMaxServiceInfoPairLength - 1, 'b')},
      {"", ""},
      {"b", ""},
  };
  AssertMakeServiceSuccess(
      string(Service::kMaxServiceIdLength, 'a'),
      MakeValidIpAddresses(),
      service_info,
      {});
}

TEST_F(ServiceTest, ShouldRejectExtraOptionsSections) {
  AssertMakeServiceFails(kValidServiceId,
                         MakeValidIpAddresses(),
                         ServiceInfo{},
                         map<string, Any>{{"not_valid", Any{"lies"}}},
                         kInvalidServiceOptions);
}

TEST_F(ServiceTest, ShouldRejectExtraMDnsOptions) {
  const map<string, Any> mdns_options{
      {"not_valid", Any{"lies"}},
  };
  const map<string, Any> options{
      {kMDNSSectionName, mdns_options},
  };
  AssertMakeServiceFails(kValidServiceId,
                         MakeValidIpAddresses(),
                         ServiceInfo{},
                         options,
                         kInvalidServiceOptions);
}

TEST_F(ServiceTest, ShouldAcceptMDnsPort) {
  const uint16_t kChosenPort = 22;
  const map<string, Any> mdns_options{
      {kMDNSPort, Any{kChosenPort}},
  };
  const map<string, Any> options{
      {kMDNSSectionName, mdns_options},
  };
  AssertMakeServiceSuccess(kValidServiceId,
                           MakeValidIpAddresses(),
                           ServiceInfo{},
                           options);
  EXPECT_EQ(service_.GetMDnsOptions().port, kChosenPort);
}

}  // namespace peerd
