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

#include <vector>

#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/fake_store.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_service.h"
#include "shill/property_store.h"
#include "shill/test_event_dispatcher.h"

using std::string;
using std::vector;
using testing::_;
using testing::NiceMock;
using testing::Return;
using testing::Test;

namespace shill {

namespace {

const char kVPNHostProperty[] = "VPN.Host";
const char kOTPProperty[] = "VPN.OTP";
const char kPinProperty[] = "VPN.PIN";
const char kPSKProperty[] = "VPN.PSK";
const char kPasswordProperty[] = "VPN.Password";
const char kPortProperty[] = "VPN.Port";

const char kPin[] = "5555";
const char kPassword[] = "random-password";
const char kPort[] = "1234";
const char kStorageID[] = "vpn_service_id";

}  // namespace

class VPNDriverUnderTest : public VPNDriver {
 public:
  explicit VPNDriverUnderTest(Manager* manager);
  VPNDriverUnderTest(const VPNDriverUnderTest&) = delete;
  VPNDriverUnderTest& operator=(const VPNDriverUnderTest&) = delete;

  ~VPNDriverUnderTest() override = default;

  // Inherited from VPNDriver.
  MOCK_METHOD(void,
              ConnectAsync,
              (const VPNService::DriverEventCallback& callback),
              (override));
  MOCK_METHOD(void, Disconnect, (), (override));
  MOCK_METHOD(IPConfig::Properties, GetIPProperties, (), (const, override));
  MOCK_METHOD(string, GetProviderType, (), (const, override));
  MOCK_METHOD(IfType, GetIfType, (), (const, override));

 private:
  static const Property kProperties[];
};

// static
const VPNDriverUnderTest::Property VPNDriverUnderTest::kProperties[] = {
    {kEapCaCertPemProperty, Property::kArray},
    {kVPNHostProperty, 0},
    {kL2tpIpsecCaCertPemProperty, Property::kArray},
    {kOTPProperty, Property::kEphemeral},
    {kPinProperty, Property::kWriteOnly},
    {kPSKProperty, Property::kCredential},
    {kPasswordProperty, Property::kCredential},
    {kPortProperty, 0},
    {kProviderTypeProperty, 0},
};

VPNDriverUnderTest::VPNDriverUnderTest(Manager* manager)
    : VPNDriver(manager, nullptr, kProperties, base::size(kProperties)) {}

class VPNDriverTest : public Test {
 public:
  VPNDriverTest()
      : manager_(&control_, &dispatcher_, &metrics_),
        device_info_(&manager_),
        driver_(&manager_) {}

  ~VPNDriverTest() override = default;

 protected:
  const base::CancelableClosure& connect_timeout_callback() const {
    return driver_.connect_timeout_callback_;
  }

  bool IsConnectTimeoutStarted() { return driver_.IsConnectTimeoutStarted(); }

  int connect_timeout_seconds() const {
    return driver_.connect_timeout_seconds();
  }

  string credential_prefix() const { return VPNDriver::kCredentialPrefix; }

  void StartConnectTimeout(int timeout_seconds) {
    driver_.StartConnectTimeout(timeout_seconds);
  }

  void StopConnectTimeout() { driver_.StopConnectTimeout(); }

  void SetArg(const string& arg, const string& value) {
    driver_.args()->Set<string>(arg, value);
  }

  void SetArgArray(const string& arg, const vector<string>& value) {
    driver_.args()->Set<Strings>(arg, value);
  }

  KeyValueStore* GetArgs() { return driver_.args(); }

  bool GetProviderPropertyString(const PropertyStore& store,
                                 const string& key,
                                 string* value);

  bool GetProviderPropertyStrings(const PropertyStore& store,
                                  const string& key,
                                  vector<string>* value);

  MockControl control_;
  EventDispatcherForTest dispatcher_;
  MockMetrics metrics_;
  MockManager manager_;
  NiceMock<MockDeviceInfo> device_info_;
  VPNDriverUnderTest driver_;
};

bool VPNDriverTest::GetProviderPropertyString(const PropertyStore& store,
                                              const string& key,
                                              string* value) {
  KeyValueStore provider_properties;
  Error error;
  EXPECT_TRUE(store.GetKeyValueStoreProperty(kProviderProperty,
                                             &provider_properties, &error));
  if (!provider_properties.Contains<string>(key)) {
    return false;
  }
  if (value != nullptr) {
    *value = provider_properties.Get<string>(key);
  }
  return true;
}

bool VPNDriverTest::GetProviderPropertyStrings(const PropertyStore& store,
                                               const string& key,
                                               vector<string>* value) {
  KeyValueStore provider_properties;
  Error error;
  EXPECT_TRUE(store.GetKeyValueStoreProperty(kProviderProperty,
                                             &provider_properties, &error));
  if (!provider_properties.Contains<Strings>(key)) {
    return false;
  }
  if (value != nullptr) {
    *value = provider_properties.Get<Strings>(key);
  }
  return true;
}

TEST_F(VPNDriverTest, Load) {
  FakeStore storage;
  GetArgs()->Set<string>(kVPNHostProperty, "1.2.3.4");
  GetArgs()->Set<string>(kPSKProperty, "1234");
  GetArgs()->Set<Strings>(kL2tpIpsecCaCertPemProperty,
                          vector<string>{"cleared-cert0", "cleared-cert1"});
  vector<string> kCaCerts{"cert0", "cert1"};
  storage.SetStringList(kStorageID, kEapCaCertPemProperty, kCaCerts);
  storage.SetString(kStorageID, kPortProperty, kPort);
  storage.SetString(kStorageID, kPinProperty, kPin);
  storage.SetString(kStorageID, credential_prefix() + kPasswordProperty,
                    kPassword);

  EXPECT_TRUE(driver_.Load(&storage, kStorageID));

  EXPECT_EQ(kCaCerts, GetArgs()->Get<Strings>(kEapCaCertPemProperty));
  EXPECT_EQ(kPort, GetArgs()->Lookup<string>(kPortProperty, ""));
  EXPECT_EQ(kPin, GetArgs()->Lookup<string>(kPinProperty, ""));
  EXPECT_EQ(kPassword, GetArgs()->Lookup<string>(kPasswordProperty, ""));

  // Properties missing from the persistent store should be deleted.
  EXPECT_FALSE(GetArgs()->Contains<string>(kVPNHostProperty));
  EXPECT_FALSE(GetArgs()->Contains<Strings>(kL2tpIpsecCaCertPemProperty));
  EXPECT_FALSE(GetArgs()->Contains<string>(kPSKProperty));
}

TEST_F(VPNDriverTest, Save) {
  SetArg(kProviderTypeProperty, kProviderOpenVpn);
  SetArg(kPinProperty, kPin);
  SetArg(kPortProperty, kPort);
  SetArg(kPasswordProperty, kPassword);
  SetArg(kOTPProperty, "987654");
  const vector<string> kCaCerts{"cert0", "cert1"};
  SetArgArray(kEapCaCertPemProperty, kCaCerts);

  FakeStore storage;
  EXPECT_TRUE(driver_.Save(&storage, kStorageID, true));

  vector<string> ca_pem;
  string provider_type, port, pin, password;
  EXPECT_TRUE(
      storage.GetStringList(kStorageID, kEapCaCertPemProperty, &ca_pem));
  EXPECT_EQ(ca_pem, kCaCerts);
  EXPECT_TRUE(
      storage.GetString(kStorageID, kProviderTypeProperty, &provider_type));
  EXPECT_EQ(provider_type, kProviderOpenVpn);
  EXPECT_TRUE(storage.GetString(kStorageID, kPortProperty, &port));
  EXPECT_EQ(port, kPort);
  EXPECT_TRUE(storage.GetString(kStorageID, kPinProperty, &pin));
  EXPECT_EQ(pin, kPin);
  EXPECT_TRUE(storage.GetString(
      kStorageID, credential_prefix() + kPasswordProperty, &password));
  EXPECT_EQ(password, kPassword);

  EXPECT_FALSE(storage.GetString(kStorageID, credential_prefix() + kPSKProperty,
                                 nullptr));
}

TEST_F(VPNDriverTest, SaveNoCredentials) {
  SetArg(kPasswordProperty, kPassword);
  SetArg(kPSKProperty, "");

  FakeStore storage;
  EXPECT_TRUE(driver_.Save(&storage, kStorageID, false));

  EXPECT_FALSE(storage.GetString(
      kStorageID, credential_prefix() + kPasswordProperty, nullptr));
  EXPECT_FALSE(storage.GetString(kStorageID, credential_prefix() + kPSKProperty,
                                 nullptr));
  EXPECT_FALSE(storage.GetString(kStorageID, kEapCaCertPemProperty, nullptr));
  EXPECT_FALSE(
      storage.GetString(kStorageID, kL2tpIpsecCaCertPemProperty, nullptr));
}

TEST_F(VPNDriverTest, UnloadCredentials) {
  SetArg(kOTPProperty, "654321");
  SetArg(kPasswordProperty, kPassword);
  SetArg(kPortProperty, kPort);
  driver_.UnloadCredentials();
  EXPECT_FALSE(GetArgs()->Contains<string>(kOTPProperty));
  EXPECT_FALSE(GetArgs()->Contains<string>(kPasswordProperty));
  EXPECT_EQ(kPort, GetArgs()->Lookup<string>(kPortProperty, ""));
}

TEST_F(VPNDriverTest, InitPropertyStore) {
  // Figure out if the store is actually hooked up to the driver argument
  // KeyValueStore.
  PropertyStore store;
  driver_.InitPropertyStore(&store);

  // An un-set property should not be readable.
  {
    Error error;
    EXPECT_FALSE(store.GetStringProperty(kPortProperty, nullptr, &error));
    EXPECT_EQ(Error::kInvalidArguments, error.type());
  }
  {
    Error error;
    EXPECT_FALSE(
        store.GetStringsProperty(kEapCaCertPemProperty, nullptr, &error));
    EXPECT_EQ(Error::kInvalidArguments, error.type());
  }
  EXPECT_FALSE(GetProviderPropertyString(store, kPortProperty, nullptr));
  EXPECT_FALSE(
      GetProviderPropertyStrings(store, kEapCaCertPemProperty, nullptr));

  const string kProviderType = "boo";
  SetArg(kPortProperty, kPort);
  SetArg(kPasswordProperty, kPassword);
  SetArg(kProviderTypeProperty, kProviderType);
  SetArg(kVPNHostProperty, "");
  const vector<string> kCaCerts{"cert1"};
  SetArgArray(kEapCaCertPemProperty, kCaCerts);
  SetArgArray(kL2tpIpsecCaCertPemProperty, vector<string>());

  // We should not be able to read a property out of the driver args using the
  // key to the args directly.
  {
    Error error;
    EXPECT_FALSE(store.GetStringProperty(kPortProperty, nullptr, &error));
    EXPECT_EQ(Error::kInvalidArguments, error.type());
  }
  {
    Error error;
    EXPECT_FALSE(
        store.GetStringsProperty(kEapCaCertPemProperty, nullptr, &error));
    EXPECT_EQ(Error::kInvalidArguments, error.type());
  }

  // We should instead be able to find it within the "Provider" stringmap.
  {
    string value;
    EXPECT_TRUE(GetProviderPropertyString(store, kPortProperty, &value));
    EXPECT_EQ(kPort, value);
  }
  {
    vector<string> value;
    EXPECT_TRUE(
        GetProviderPropertyStrings(store, kEapCaCertPemProperty, &value));
    EXPECT_EQ(kCaCerts, value);
  }

  // We should be able to read empty properties from the "Provider" stringmap.
  {
    string value;
    EXPECT_TRUE(GetProviderPropertyString(store, kVPNHostProperty, &value));
    EXPECT_TRUE(value.empty());
  }
  {
    vector<string> value;
    EXPECT_TRUE(
        GetProviderPropertyStrings(store, kL2tpIpsecCaCertPemProperty, &value));
    EXPECT_TRUE(value.empty());
  }

  // Properties that start with the prefix "Provider." should be mapped to the
  // name in the Properties dict with the prefix removed.
  {
    string value;
    EXPECT_TRUE(GetProviderPropertyString(store, kTypeProperty, &value));
    EXPECT_EQ(kProviderType, value);
  }

  // If we clear a property, we should no longer be able to find it.
  {
    Error error;
    EXPECT_TRUE(store.ClearProperty(kPortProperty, &error));
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_FALSE(GetProviderPropertyString(store, kPortProperty, nullptr));
  }
  {
    Error error;
    EXPECT_TRUE(store.ClearProperty(kEapCaCertPemProperty, &error));
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_FALSE(
        GetProviderPropertyStrings(store, kEapCaCertPemProperty, nullptr));
  }

  // A second attempt to clear this property should return an error.
  {
    Error error;
    EXPECT_FALSE(store.ClearProperty(kPortProperty, &error));
    EXPECT_EQ(Error::kNotFound, error.type());
  }
  {
    Error error;
    EXPECT_FALSE(store.ClearProperty(kEapCaCertPemProperty, &error));
    EXPECT_EQ(Error::kNotFound, error.type());
  }

  // Test write only properties.
  EXPECT_FALSE(GetProviderPropertyString(store, kPinProperty, nullptr));

  // Write properties to the driver args using the PropertyStore interface.
  {
    const string kValue = "some-value";
    Error error;
    EXPECT_TRUE(store.SetStringProperty(kPinProperty, kValue, &error));
    EXPECT_EQ(kValue, GetArgs()->Get<string>(kPinProperty));
  }
  {
    const vector<string> kValue{"some-value"};
    Error error;
    EXPECT_TRUE(
        store.SetStringsProperty(kEapCaCertPemProperty, kValue, &error));
    EXPECT_EQ(kValue, GetArgs()->Get<Strings>(kEapCaCertPemProperty));
  }
}

TEST_F(VPNDriverTest, ConnectTimeout) {
  EXPECT_TRUE(connect_timeout_callback().IsCancelled());
  EXPECT_FALSE(IsConnectTimeoutStarted());
  StartConnectTimeout(0);
  EXPECT_EQ(0, connect_timeout_seconds());
  EXPECT_FALSE(connect_timeout_callback().IsCancelled());
  EXPECT_TRUE(IsConnectTimeoutStarted());
  StartConnectTimeout(10);  // This should take no effect.
  EXPECT_EQ(0, connect_timeout_seconds());
  dispatcher_.DispatchPendingEvents();
  EXPECT_TRUE(connect_timeout_callback().IsCancelled());
  EXPECT_FALSE(IsConnectTimeoutStarted());
}

TEST_F(VPNDriverTest, StartStopConnectTimeout) {
  EXPECT_FALSE(IsConnectTimeoutStarted());
  EXPECT_EQ(0, connect_timeout_seconds());
  const int kTimeout = 123;
  StartConnectTimeout(kTimeout);
  EXPECT_TRUE(IsConnectTimeoutStarted());
  EXPECT_EQ(kTimeout, connect_timeout_seconds());
  StartConnectTimeout(kTimeout - 20);
  EXPECT_EQ(kTimeout, connect_timeout_seconds());
  StopConnectTimeout();
  EXPECT_FALSE(IsConnectTimeoutStarted());
  EXPECT_EQ(0, connect_timeout_seconds());
}

}  // namespace shill
