// Copyright (c) 2012 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 <set>

#include "shill/vpn_provider.h"

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

#include "shill/error.h"
#include "shill/nice_mock_control.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_device_info.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_profile.h"
#include "shill/mock_store.h"
#include "shill/mock_vpn_driver.h"
#include "shill/mock_vpn_service.h"

using std::string;
using testing::_;
using testing::DoAll;
using testing::NiceMock;
using testing::Return;
using testing::SetArgumentPointee;

namespace shill {

class VPNProviderTest : public testing::Test {
 public:
  VPNProviderTest()
      : metrics_(NULL),
        manager_(&control_, NULL, &metrics_, NULL),
        device_info_(&control_, NULL, &metrics_, &manager_),
        provider_(&control_, NULL, &metrics_, &manager_) {}

  virtual ~VPNProviderTest() {}

 protected:
  static const char kHost[];
  static const char kName[];

  string GetServiceFriendlyName(const ServiceRefPtr &service) {
    return service->friendly_name();
  }

  void SetConnectState(const ServiceRefPtr &service,
                       Service::ConnectState state) {
    service->state_ = state;
  }

  void AddService(const VPNServiceRefPtr &service) {
    provider_.services_.push_back(service);
  }

  VPNServiceRefPtr GetServiceAt(int idx) {
    return provider_.services_[idx];
  }

  size_t GetServiceCount() const {
    return provider_.services_.size();
  }

  NiceMockControl control_;
  MockMetrics metrics_;
  MockManager manager_;
  MockDeviceInfo device_info_;
  VPNProvider provider_;
};

const char VPNProviderTest::kHost[] = "10.8.0.1";
const char VPNProviderTest::kName[] = "vpn-name";

TEST_F(VPNProviderTest, GetServiceNoType) {
  KeyValueStore args;
  Error e;
  args.SetString(kTypeProperty, kTypeVPN);
  ServiceRefPtr service = provider_.GetService(args, &e);
  EXPECT_EQ(Error::kNotSupported, e.type());
  EXPECT_FALSE(service);
}

TEST_F(VPNProviderTest, GetServiceUnsupportedType) {
  KeyValueStore args;
  Error e;
  args.SetString(kTypeProperty, kTypeVPN);
  args.SetString(kProviderTypeProperty, "unknown-vpn-type");
  args.SetString(kProviderHostProperty, kHost);
  args.SetString(kNameProperty, kName);
  ServiceRefPtr service = provider_.GetService(args, &e);
  EXPECT_EQ(Error::kNotSupported, e.type());
  EXPECT_FALSE(service);
}

TEST_F(VPNProviderTest, GetService) {
  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeVPN);
  args.SetString(kProviderTypeProperty, kProviderOpenVpn);
  args.SetString(kProviderHostProperty, kHost);
  args.SetString(kNameProperty, kName);

  {
    Error error;
    ServiceRefPtr service = provider_.FindSimilarService(args, &error);
    EXPECT_EQ(Error::kNotFound, error.type());
    EXPECT_EQ(NULL, service.get());
  }

  EXPECT_EQ(0, GetServiceCount());

  ServiceRefPtr service;
  {
    Error error;
    EXPECT_CALL(manager_, device_info()).WillOnce(Return(&device_info_));
    EXPECT_CALL(manager_, RegisterService(_));
    service = provider_.GetService(args, &error);
    EXPECT_TRUE(error.IsSuccess());
    ASSERT_TRUE(service);
    testing::Mock::VerifyAndClearExpectations(&manager_);
  }

  EXPECT_EQ("vpn_10_8_0_1_vpn_name", service->GetStorageIdentifier());
  EXPECT_EQ(kName, GetServiceFriendlyName(service));

  EXPECT_EQ(1, GetServiceCount());

  // Configure the service to set its properties (including Provider.Host).
  {
    Error error;
    service->Configure(args, &error);
    EXPECT_TRUE(error.IsSuccess());
  }

  // None of the calls below should cause a new service to be registered.
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);

  // A second call should return the same service.
  {
    Error error;
    ServiceRefPtr get_service = provider_.GetService(args, &error);
    EXPECT_TRUE(error.IsSuccess());
    ASSERT_EQ(service, get_service);
  }

  EXPECT_EQ(1, GetServiceCount());

  // FindSimilarService should also return this service.
  {
    Error error;
    ServiceRefPtr similar_service = provider_.FindSimilarService(args, &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_EQ(service, similar_service);
  }

  EXPECT_EQ(1, GetServiceCount());

  // However, CreateTemporaryService should create a different service.
  {
    Error error;
    ServiceRefPtr temporary_service =
        provider_.CreateTemporaryService(args, &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_NE(service, temporary_service);

    // However this service will not be part of the provider.
    EXPECT_EQ(1, GetServiceCount());
  }
}

TEST_F(VPNProviderTest, OnDeviceInfoAvailable) {
  const string kInterfaceName("tun0");
  const int kInterfaceIndex = 1;

  scoped_ptr<MockVPNDriver> bad_driver(new MockVPNDriver());
  EXPECT_CALL(*bad_driver.get(), ClaimInterface(_, _))
      .Times(2)
      .WillRepeatedly(Return(false));
  provider_.services_.push_back(
      new VPNService(&control_, NULL, &metrics_, NULL, bad_driver.release()));

  EXPECT_FALSE(provider_.OnDeviceInfoAvailable(kInterfaceName,
                                               kInterfaceIndex));

  scoped_ptr<MockVPNDriver> good_driver(new MockVPNDriver());
  EXPECT_CALL(*good_driver.get(), ClaimInterface(_, _))
      .WillOnce(Return(true));
  provider_.services_.push_back(
      new VPNService(&control_, NULL, &metrics_, NULL, good_driver.release()));

  scoped_ptr<MockVPNDriver> dup_driver(new MockVPNDriver());
  EXPECT_CALL(*dup_driver.get(), ClaimInterface(_, _))
      .Times(0);
  provider_.services_.push_back(
      new VPNService(&control_, NULL, &metrics_, NULL, dup_driver.release()));

  EXPECT_TRUE(provider_.OnDeviceInfoAvailable(kInterfaceName, kInterfaceIndex));
  provider_.services_.clear();
}

TEST_F(VPNProviderTest, RemoveService) {
  scoped_refptr<MockVPNService> service0(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
  scoped_refptr<MockVPNService> service1(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
  scoped_refptr<MockVPNService> service2(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));

  provider_.services_.push_back(service0.get());
  provider_.services_.push_back(service1.get());
  provider_.services_.push_back(service2.get());

  ASSERT_EQ(3, provider_.services_.size());

  provider_.RemoveService(service1);

  EXPECT_EQ(2, provider_.services_.size());
  EXPECT_EQ(service0, provider_.services_[0]);
  EXPECT_EQ(service2, provider_.services_[1]);

  provider_.RemoveService(service2);

  EXPECT_EQ(1, provider_.services_.size());
  EXPECT_EQ(service0, provider_.services_[0]);

  provider_.RemoveService(service0);
  EXPECT_EQ(0, provider_.services_.size());
}

MATCHER_P(ServiceWithStorageId, storage_id, "") {
  return arg->GetStorageIdentifier() == storage_id;
}

TEST_F(VPNProviderTest, CreateServicesFromProfile) {
  scoped_refptr<MockProfile> profile(
      new NiceMock<MockProfile>(&control_, &metrics_, &manager_, ""));
  NiceMock<MockStore> storage;
  EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(&storage));
  EXPECT_CALL(storage, GetString(_, _, _)).WillRepeatedly(Return(false));

  std::set<string> groups;

  const string kNonVPNIdentifier("foo_1");
  groups.insert(kNonVPNIdentifier);

  const string kVPNIdentifierNoProvider("vpn_no_provider");
  groups.insert(kVPNIdentifierNoProvider);

  const string kVPNIdentifierNoName("vpn_no_name");
  groups.insert(kVPNIdentifierNoName);
  const string kOpenVPNProvider(kProviderOpenVpn);
  EXPECT_CALL(storage,
              GetString(kVPNIdentifierNoName, kProviderTypeProperty, _))
      .WillRepeatedly(
           DoAll(SetArgumentPointee<2>(kOpenVPNProvider), Return(true)));

  const string kVPNIdentifierNoHost("vpn_no_host");
  groups.insert(kVPNIdentifierNoHost);
  EXPECT_CALL(storage,
              GetString(kVPNIdentifierNoHost, kProviderTypeProperty, _))
      .WillRepeatedly(
           DoAll(SetArgumentPointee<2>(kOpenVPNProvider), Return(true)));
  const string kName("name");
  EXPECT_CALL(storage, GetString(kVPNIdentifierNoHost, kNameProperty, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));

  const string kVPNIdentifierValid("vpn_valid");
  groups.insert(kVPNIdentifierValid);
  EXPECT_CALL(storage, GetString(kVPNIdentifierValid, kProviderTypeProperty, _))
      .WillRepeatedly(
           DoAll(SetArgumentPointee<2>(kOpenVPNProvider), Return(true)));
  EXPECT_CALL(storage, GetString(kVPNIdentifierValid, kNameProperty, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));
  const string kHost("1.2.3.4");
  EXPECT_CALL(storage, GetString(kVPNIdentifierValid, kProviderHostProperty, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHost), Return(true)));

  EXPECT_CALL(storage, GetGroupsWithKey(kProviderTypeProperty))
      .WillRepeatedly(Return(groups));

  EXPECT_CALL(manager_, device_info())
      .WillRepeatedly(Return(reinterpret_cast<DeviceInfo *>(NULL)));
  EXPECT_CALL(manager_,
              RegisterService(ServiceWithStorageId(kVPNIdentifierValid)));
  EXPECT_CALL(*profile,
              ConfigureService(ServiceWithStorageId(kVPNIdentifierValid)))
      .WillOnce(Return(true));
  provider_.CreateServicesFromProfile(profile);

  GetServiceAt(0)->driver()->args()->SetString(kProviderHostProperty, kHost);
  // Calling this again should not create any more services (checked by the
  // Times(1) above).
  provider_.CreateServicesFromProfile(profile);
}

TEST_F(VPNProviderTest, CreateService) {
  static const char kName[] = "test-vpn-service";
  static const char kStorageID[] = "test_vpn_storage_id";
  static const char *kTypes[] = {
    kProviderOpenVpn,
    kProviderL2tpIpsec,
  };
  const size_t kTypesCount = arraysize(kTypes);
  EXPECT_CALL(manager_, device_info())
      .Times(kTypesCount)
      .WillRepeatedly(Return(&device_info_));
  EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount);
  for (size_t i = 0; i < kTypesCount; i++) {
    Error error;
    VPNServiceRefPtr service =
        provider_.CreateService(kTypes[i], kName, kStorageID, &error);
    ASSERT_TRUE(service) << kTypes[i];
    ASSERT_TRUE(service->driver()) << kTypes[i];
    EXPECT_EQ(kTypes[i], service->driver()->GetProviderType());
    EXPECT_EQ(kName, GetServiceFriendlyName(service)) << kTypes[i];
    EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i];
    EXPECT_TRUE(error.IsSuccess()) << kTypes[i];
  }
  Error error;
  VPNServiceRefPtr unknown_service =
      provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error);
  EXPECT_FALSE(unknown_service);
  EXPECT_EQ(Error::kNotSupported, error.type());
}

TEST_F(VPNProviderTest, HasActiveService) {
  EXPECT_FALSE(provider_.HasActiveService());

  scoped_refptr<MockVPNService> service0(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
  scoped_refptr<MockVPNService> service1(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
  scoped_refptr<MockVPNService> service2(
      new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));

  AddService(service0);
  AddService(service1);
  AddService(service2);
  EXPECT_FALSE(provider_.HasActiveService());

  SetConnectState(service1, Service::kStateAssociating);
  EXPECT_TRUE(provider_.HasActiveService());

  SetConnectState(service1, Service::kStateOnline);
  EXPECT_TRUE(provider_.HasActiveService());
}

}  // namespace shill
