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

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

#include "shill/ipconfig.h"
#include "shill/mock_control.h"
#include "shill/mock_ipconfig.h"
#include "shill/mock_store.h"
#include "shill/property_store.h"

using std::string;
using std::vector;
using testing::_;
using testing::DoAll;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::Test;

namespace shill {

namespace {

const char kAddress[] = "10.0.0.1";
const char kGateway[] = "10.0.0.254";
const int32_t kMtu = 512;

const char kNameServer0[] = "10.0.1.253";
const char kNameServer1[] = "10.0.1.252";
const char kNameServers[] = "10.0.1.253,10.0.1.252";

const char kSearchDomains[] = "example.com,chromium.org";
const char kSearchDomain0[] = "example.com";
const char kSearchDomain1[] = "chromium.org";

const char kPeerAddress[] = "10.0.0.2";
const int32_t kPrefixLen = 24;

const char kExcludedRoutes[] = "192.168.1.0/24,192.168.2.0/24";
const char kExcludedRoute0[] = "192.168.1.0/24";
const char kExcludedRoute1[] = "192.168.2.0/24";

const char kIncludedRoutes[] = "0.0.0.0/0";
const IPConfig::Route kIncludedRoute0("0.0.0.0", 0, "10.0.0.254");

}  // namespace

class StaticIPParametersTest : public Test {
 public:
  StaticIPParametersTest() = default;

  void ExpectEmptyIPConfig() {
    EXPECT_TRUE(ipconfig_props_.address.empty());
    EXPECT_TRUE(ipconfig_props_.gateway.empty());
    EXPECT_EQ(IPConfig::kUndefinedMTU, ipconfig_props_.mtu);
    EXPECT_TRUE(ipconfig_props_.dns_servers.empty());
    EXPECT_TRUE(ipconfig_props_.domain_search.empty());
    EXPECT_TRUE(ipconfig_props_.peer_address.empty());
    EXPECT_FALSE(ipconfig_props_.subnet_prefix);
    EXPECT_TRUE(ipconfig_props_.exclusion_list.empty());
    EXPECT_TRUE(ipconfig_props_.routes.empty());
  }
  // Modify an IP address string in some predictable way.  There's no need
  // for the output string to be valid from a networking perspective.
  string VersionedAddress(const string& address, int version) {
    string returned_address = address;
    CHECK(returned_address.length());
    returned_address[returned_address.length() - 1] += version;
    return returned_address;
  }
  void ExpectPopulatedIPConfigWithVersion(int version) {
    EXPECT_EQ(VersionedAddress(kAddress, version), ipconfig_props_.address);
    EXPECT_EQ(VersionedAddress(kGateway, version), ipconfig_props_.gateway);
    EXPECT_EQ(kMtu + version, ipconfig_props_.mtu);

    EXPECT_EQ(2, ipconfig_props_.dns_servers.size());
    EXPECT_EQ(VersionedAddress(kNameServer0, version),
              ipconfig_props_.dns_servers[0]);
    EXPECT_EQ(VersionedAddress(kNameServer1, version),
              ipconfig_props_.dns_servers[1]);

    // VersionedAddress() increments the final character of each domain
    // name.
    EXPECT_EQ(2, ipconfig_props_.domain_search.size());
    EXPECT_EQ(VersionedAddress(kSearchDomain0, version),
              ipconfig_props_.domain_search[0]);
    EXPECT_EQ(VersionedAddress(kSearchDomain1, version),
              ipconfig_props_.domain_search[1]);

    EXPECT_EQ(VersionedAddress(kPeerAddress, version),
              ipconfig_props_.peer_address);
    EXPECT_EQ(kPrefixLen + version, ipconfig_props_.subnet_prefix);

    EXPECT_EQ(2, ipconfig_props_.exclusion_list.size());
    EXPECT_EQ(VersionedAddress(kExcludedRoute0, version),
              ipconfig_props_.exclusion_list[0]);
    EXPECT_EQ(VersionedAddress(kExcludedRoute1, version),
              ipconfig_props_.exclusion_list[1]);

    // VersionedAddress() increments the final digit of the prefix on
    // the IncludedRoutes property, and the final digit of the IP address
    // on the Gateway property.
    EXPECT_EQ(1, ipconfig_props_.routes.size());
    EXPECT_EQ(kIncludedRoute0.host, ipconfig_props_.routes[0].host);
    EXPECT_EQ(kIncludedRoute0.prefix + version,
              ipconfig_props_.routes[0].prefix);
    EXPECT_EQ(VersionedAddress(kIncludedRoute0.gateway, version),
              ipconfig_props_.routes[0].gateway);
  }
  void ExpectPopulatedIPConfig() { ExpectPopulatedIPConfigWithVersion(0); }
  void ExpectPropertiesWithVersion(PropertyStore* store,
                                   const string& property_prefix,
                                   int version) {
    KeyValueStore args;
    Error unused_error;
    EXPECT_TRUE(store->GetKeyValueStoreProperty(property_prefix + "Config",
                                                &args, &unused_error));
    EXPECT_EQ(VersionedAddress(kAddress, version),
              args.GetString(kAddressProperty));
    EXPECT_EQ(VersionedAddress(kGateway, version),
              args.GetString(kGatewayProperty));
    EXPECT_EQ(kMtu + version, args.GetInt(kMtuProperty));
    vector<string> kTestNameServers({VersionedAddress(kNameServer0, version),
                                     VersionedAddress(kNameServer1, version)});
    EXPECT_EQ(kTestNameServers, args.GetStrings(kNameServersProperty));
    vector<string> kTestSearchDomains(
        {VersionedAddress(kSearchDomain0, version),
         VersionedAddress(kSearchDomain1, version)});
    EXPECT_EQ(kTestSearchDomains, args.GetStrings(kSearchDomainsProperty));
    EXPECT_EQ(VersionedAddress(kPeerAddress, version),
              args.GetString(kPeerAddressProperty));
    EXPECT_EQ(kPrefixLen + version, args.GetInt(kPrefixlenProperty));
    vector<string> kTestExcludedRoutes(
        {VersionedAddress(kExcludedRoute0, version),
         VersionedAddress(kExcludedRoute1, version)});
    EXPECT_EQ(kTestExcludedRoutes, args.GetStrings(kExcludedRoutesProperty));
    vector<string> kTestIncludedRoutes(
        {VersionedAddress(kIncludedRoutes, version)});
    EXPECT_EQ(kTestIncludedRoutes, args.GetStrings(kIncludedRoutesProperty));
  }
  void ExpectProperties(PropertyStore* store, const string& property_prefix) {
    ExpectPropertiesWithVersion(store, property_prefix, 0);
  }
  void PopulateIPConfig() {
    ipconfig_props_.address = kAddress;
    ipconfig_props_.gateway = kGateway;
    ipconfig_props_.mtu = kMtu;
    ipconfig_props_.dns_servers = {kNameServer0, kNameServer1};
    ipconfig_props_.domain_search = {kSearchDomain0, kSearchDomain1};
    ipconfig_props_.peer_address = kPeerAddress;
    ipconfig_props_.subnet_prefix = kPrefixLen;
    ipconfig_props_.exclusion_list = {kExcludedRoute0, kExcludedRoute1};
    ipconfig_props_.routes = {kIncludedRoute0};
  }
  void SetStaticProperties(PropertyStore* store) {
    SetStaticPropertiesWithVersion(store, 0);
  }
  void SetStaticPropertiesWithVersion(PropertyStore* store, int version) {
    KeyValueStore args;
    args.SetString(kAddressProperty, VersionedAddress(kAddress, version));
    args.SetString(kGatewayProperty, VersionedAddress(kGateway, version));
    args.SetInt(kMtuProperty, kMtu + version);
    args.SetStrings(kNameServersProperty,
                    {VersionedAddress(kNameServer0, version),
                     VersionedAddress(kNameServer1, version)});
    args.SetStrings(kSearchDomainsProperty,
                    {VersionedAddress(kSearchDomain0, version),
                     VersionedAddress(kSearchDomain1, version)});
    args.SetString(kPeerAddressProperty,
                   VersionedAddress(kPeerAddress, version));
    args.SetInt(kPrefixlenProperty, kPrefixLen + version);
    args.SetStrings(kExcludedRoutesProperty,
                    {VersionedAddress(kExcludedRoute0, version),
                     VersionedAddress(kExcludedRoute1, version)});
    args.SetStrings(kIncludedRoutesProperty,
                    {VersionedAddress(kIncludedRoutes, version)});

    Error error;
    store->SetKeyValueStoreProperty(kStaticIPConfigProperty, args, &error);
  }
  KeyValueStore* static_args() { return &static_params_.args_; }
  KeyValueStore* saved_args() { return &static_params_.saved_args_; }

 protected:
  StaticIPParameters static_params_;
  IPConfig::Properties ipconfig_props_;
};

TEST_F(StaticIPParametersTest, InitState) {
  ExpectEmptyIPConfig();

  // Applying an empty set of parameters on an empty set of properties should
  // be a no-op.
  static_params_.ApplyTo(&ipconfig_props_);
  ExpectEmptyIPConfig();
}

TEST_F(StaticIPParametersTest, ApplyEmptyParameters) {
  PopulateIPConfig();
  static_params_.ApplyTo(&ipconfig_props_);
  ExpectPopulatedIPConfig();
}

TEST_F(StaticIPParametersTest, ControlInterface) {
  PropertyStore store;
  int version = 0;
  static_params_.PlumbPropertyStore(&store);
  SetStaticProperties(&store);
  static_params_.ApplyTo(&ipconfig_props_);
  ExpectPopulatedIPConfig();

  EXPECT_TRUE(static_params_.ContainsAddress());
  EXPECT_TRUE(store.Contains("StaticIPConfig"));
  static_args()->Remove("Address");
  EXPECT_FALSE(static_params_.ContainsAddress());
  static_args()->Remove("Mtu");
  IPConfig::Properties props;
  const string kTestAddress("test_address");
  props.address = kTestAddress;
  const int32_t kTestMtu = 256;
  props.mtu = kTestMtu;
  static_params_.ApplyTo(&props);
  EXPECT_EQ(kTestAddress, props.address);
  EXPECT_EQ(kTestMtu, props.mtu);

  EXPECT_FALSE(static_args()->ContainsString("Address"));
  EXPECT_EQ(kGateway, static_args()->GetString("Gateway"));
  EXPECT_FALSE(static_args()->ContainsInt("Mtu"));
  vector<string> kTestNameServers({VersionedAddress(kNameServer0, version),
                                   VersionedAddress(kNameServer1, version)});
  EXPECT_EQ(kTestNameServers, static_args()->GetStrings("NameServers"));
  vector<string> kTestSearchDomains(
      {VersionedAddress(kSearchDomain0, version),
       VersionedAddress(kSearchDomain1, version)});
  EXPECT_EQ(kTestSearchDomains, static_args()->GetStrings("SearchDomains"));
  EXPECT_EQ(VersionedAddress(kPeerAddress, version),
            static_args()->GetString("PeerAddress"));
  EXPECT_EQ(kPrefixLen + version, static_args()->GetInt("Prefixlen"));
  vector<string> kTestExcludedRoutes(
      {VersionedAddress(kExcludedRoute0, version),
       VersionedAddress(kExcludedRoute1, version)});
  EXPECT_EQ(kTestExcludedRoutes, static_args()->GetStrings("ExcludedRoutes"));
  vector<string> kTestIncludedRoutes(
      {VersionedAddress(kIncludedRoutes, version)});
  EXPECT_EQ(kTestIncludedRoutes, static_args()->GetStrings("IncludedRoutes"));
}

TEST_F(StaticIPParametersTest, Profile) {
  StrictMock<MockStore> store;
  const string kID = "storage_id";
  EXPECT_CALL(store, GetString(kID, "StaticIP.Address", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kAddress)), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.Gateway", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kGateway)), Return(true)));
  EXPECT_CALL(store, GetInt(kID, "StaticIP.Mtu", _))
      .WillOnce(DoAll(SetArgPointee<2>(kMtu), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.NameServers", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kNameServers)), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.SearchDomains", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kSearchDomains)), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.PeerAddress", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kPeerAddress)), Return(true)));
  EXPECT_CALL(store, GetInt(kID, "StaticIP.Prefixlen", _))
      .WillOnce(DoAll(SetArgPointee<2>(kPrefixLen), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.ExcludedRoutes", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kExcludedRoutes)), Return(true)));
  EXPECT_CALL(store, GetString(kID, "StaticIP.IncludedRoutes", _))
      .WillOnce(DoAll(SetArgPointee<2>(string(kIncludedRoutes)), Return(true)));
  static_params_.Load(&store, kID);
  static_params_.ApplyTo(&ipconfig_props_);
  ExpectPopulatedIPConfig();

  EXPECT_CALL(store, SetString(kID, "StaticIP.Address", kAddress))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.Gateway", kGateway))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetInt(kID, "StaticIP.Mtu", kMtu)).WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.NameServers", kNameServers))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.SearchDomains", kSearchDomains))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.PeerAddress", kPeerAddress))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetInt(kID, "StaticIP.Prefixlen", kPrefixLen))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.ExcludedRoutes", kExcludedRoutes))
      .WillOnce(Return(true));
  EXPECT_CALL(store, SetString(kID, "StaticIP.IncludedRoutes", kIncludedRoutes))
      .WillOnce(Return(true));
  static_params_.Save(&store, kID);
}

TEST_F(StaticIPParametersTest, SavedParameters) {
  // Calling RestoreTo() when no parameters are set should not crash or
  // add any entries.
  static_params_.RestoreTo(&ipconfig_props_);
  ExpectEmptyIPConfig();

  PopulateIPConfig();
  PropertyStore static_params_props;
  static_params_.PlumbPropertyStore(&static_params_props);
  SetStaticPropertiesWithVersion(&static_params_props, 1);
  static_params_.ApplyTo(&ipconfig_props_);

  // The version 0 properties in |ipconfig_props_| are now in SavedIP.*
  // properties, while the version 1 StaticIP parameters are now in
  // |ipconfig_props_|.
  ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 0);
  ExpectPopulatedIPConfigWithVersion(1);

  // Clear all "StaticIP" parameters.
  static_args()->Clear();

  // Another ApplyTo() call rotates the version 1 properties in
  // |ipconfig_props_| over to SavedIP.*.  Since there are no StaticIP
  // parameters, |ipconfig_props_| should remain populated with version 1
  // parameters.
  static_params_.ApplyTo(&ipconfig_props_);
  ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 1);
  ExpectPopulatedIPConfigWithVersion(1);

  // Reset |ipconfig_props_| to version 0.
  PopulateIPConfig();

  // A RestoreTo() call moves the version 1 "SavedIP" parameters into
  // |ipconfig_props_|.
  SetStaticPropertiesWithVersion(&static_params_props, 2);
  static_params_.RestoreTo(&ipconfig_props_);
  ExpectPopulatedIPConfigWithVersion(1);

  // All "SavedIP" parameters should be cleared.
  EXPECT_TRUE(saved_args()->IsEmpty());

  // Static IP parameters should be unchanged.
  ExpectPropertiesWithVersion(&static_params_props, "StaticIP", 2);
}

TEST_F(StaticIPParametersTest, IPConfigRefreshed) {
  MockControl control;
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(&control, "int0");
  static_params_.SetIPConfig(ipconfig->weak_ptr_factory_.GetWeakPtr());
  EXPECT_CALL(*ipconfig, Refresh());
  PropertyStore store;
  static_params_.PlumbPropertyStore(&store);
  SetStaticProperties(&store);
}

}  // namespace shill
