//
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "apmanager/config.h"

#include <string>

#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#if !defined(__ANDROID__)
#include <chromeos/dbus/service_constants.h>
#else
#include "dbus/apmanager/dbus-constants.h"
#endif

#include "apmanager/error.h"
#include "apmanager/fake_config_adaptor.h"
#include "apmanager/fake_device_adaptor.h"
#include "apmanager/mock_control.h"
#include "apmanager/mock_device.h"
#include "apmanager/mock_manager.h"

using ::testing::_;
using ::testing::Mock;
using ::testing::Return;
using ::testing::ReturnNew;
using ::testing::SetArgumentPointee;
namespace apmanager {

namespace {

const char kSsid[] = "TestSsid";
const char kInterface[] = "uap0";
const char kBridgeInterface[] = "br0";
const char kControlInterfacePath[] = "/var/run/apmanager/hostapd/ctrl_iface";
const char kPassphrase[] = "Passphrase";
const char k24GHzHTCapab[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
const char k5GHzHTCapab[] =
    "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";

const uint16_t k24GHzChannel = 6;
const uint16_t k5GHzChannel = 36;

const char kExpected80211gConfigContent[] = "ssid=TestSsid\n"
                                            "channel=6\n"
                                            "interface=uap0\n"
                                            "hw_mode=g\n"
                                            "driver=nl80211\n"
                                            "fragm_threshold=2346\n"
                                            "rts_threshold=2347\n";

const char kExpected80211gBridgeConfigContent[] = "ssid=TestSsid\n"
                                                  "bridge=br0\n"
                                                  "channel=6\n"
                                                  "interface=uap0\n"
                                                  "hw_mode=g\n"
                                                  "driver=nl80211\n"
                                                  "fragm_threshold=2346\n"
                                                  "rts_threshold=2347\n";

const char kExpected80211gCtrlIfaceConfigContent[] =
    "ssid=TestSsid\n"
    "channel=6\n"
    "interface=uap0\n"
    "hw_mode=g\n"
    "ctrl_interface=/var/run/apmanager/hostapd/ctrl_iface\n"
#if !defined(__ANDROID__)
    "ctrl_interface_group=apmanager\n"
#else
    "ctrl_interface_group=system\n"
#endif  // __ANDROID__
    "driver=nl80211\n"
    "fragm_threshold=2346\n"
    "rts_threshold=2347\n";

const char kExpected80211n5GHzConfigContent[] =
    "ssid=TestSsid\n"
    "channel=36\n"
    "interface=uap0\n"
    "ieee80211n=1\n"
    "ht_capab=[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]\n"
    "hw_mode=a\n"
    "driver=nl80211\n"
    "fragm_threshold=2346\n"
    "rts_threshold=2347\n";

const char kExpected80211n24GHzConfigContent[] =
    "ssid=TestSsid\n"
    "channel=6\n"
    "interface=uap0\n"
    "ieee80211n=1\n"
    "ht_capab=[LDPC SMPS-STATIC GF SHORT-GI-20]\n"
    "hw_mode=g\n"
    "driver=nl80211\n"
    "fragm_threshold=2346\n"
    "rts_threshold=2347\n";

const char kExpectedRsnConfigContent[] = "ssid=TestSsid\n"
                                         "channel=6\n"
                                         "interface=uap0\n"
                                         "hw_mode=g\n"
                                         "wpa=2\n"
                                         "rsn_pairwise=CCMP\n"
                                         "wpa_key_mgmt=WPA-PSK\n"
                                         "wpa_passphrase=Passphrase\n"
                                         "driver=nl80211\n"
                                         "fragm_threshold=2346\n"
                                         "rts_threshold=2347\n";

}  // namespace

class ConfigTest : public testing::Test {
 public:
  ConfigTest()
      : manager_(&control_interface_) {
    ON_CALL(control_interface_, CreateDeviceAdaptorRaw())
        .WillByDefault(ReturnNew<FakeDeviceAdaptor>());
    ON_CALL(control_interface_, CreateConfigAdaptorRaw())
        .WillByDefault(ReturnNew<FakeConfigAdaptor>());
    // Defer creation of Config object to allow ControlInterface to setup
    // expectations for generating fake adaptors.
    config_.reset(new Config(&manager_, 0));
  }

  void SetupDevice(const std::string& interface) {
    // Setup mock device.
    device_ = new MockDevice(&manager_);
    device_->SetPreferredApInterface(interface);
    EXPECT_CALL(manager_, GetDeviceFromInterfaceName(interface))
        .WillRepeatedly(Return(device_));
  }

  void VerifyError(const Error& error,
                   Error::Type expected_type,
                   const std::string& expected_message_start) {
    EXPECT_EQ(expected_type, error.type());
    EXPECT_TRUE(
        base::StartsWithASCII(error.message(), expected_message_start, false));
  }

 protected:
  MockControl control_interface_;
  MockManager manager_;
  scoped_refptr<MockDevice> device_;
  std::unique_ptr<Config> config_;
};

TEST_F(ConfigTest, GetFrequencyFromChannel) {
  uint32_t frequency;
  // Invalid channel.
  EXPECT_FALSE(Config::GetFrequencyFromChannel(0, &frequency));
  EXPECT_FALSE(Config::GetFrequencyFromChannel(166, &frequency));
  EXPECT_FALSE(Config::GetFrequencyFromChannel(14, &frequency));
  EXPECT_FALSE(Config::GetFrequencyFromChannel(33, &frequency));

  // Valid channel.
  const uint32_t kChannel1Frequency = 2412;
  const uint32_t kChannel13Frequency = 2472;
  const uint32_t kChannel34Frequency = 5170;
  const uint32_t kChannel165Frequency = 5825;
  EXPECT_TRUE(Config::GetFrequencyFromChannel(1, &frequency));
  EXPECT_EQ(kChannel1Frequency, frequency);
  EXPECT_TRUE(Config::GetFrequencyFromChannel(13, &frequency));
  EXPECT_EQ(kChannel13Frequency, frequency);
  EXPECT_TRUE(Config::GetFrequencyFromChannel(34, &frequency));
  EXPECT_EQ(kChannel34Frequency, frequency);
  EXPECT_TRUE(Config::GetFrequencyFromChannel(165, &frequency));
  EXPECT_EQ(kChannel165Frequency, frequency);
}

TEST_F(ConfigTest, ValidateSsid) {
  Error error;
  // SSID must contain between 1 and 32 characters.
  EXPECT_TRUE(config_->ValidateSsid(&error, "s"));
  EXPECT_TRUE(config_->ValidateSsid(&error, std::string(32, 'c')));
  EXPECT_FALSE(config_->ValidateSsid(&error, ""));
  EXPECT_FALSE(config_->ValidateSsid(&error, std::string(33, 'c')));
}

TEST_F(ConfigTest, ValidateSecurityMode) {
  Error error;
  EXPECT_TRUE(config_->ValidateSecurityMode(&error, kSecurityModeNone));
  EXPECT_TRUE(config_->ValidateSecurityMode(&error, kSecurityModeRSN));
  EXPECT_FALSE(config_->ValidateSecurityMode(&error, "InvalidSecurityMode"));
}

TEST_F(ConfigTest, ValidatePassphrase) {
  Error error;
  // Passpharse must contain between 8 and 63 characters.
  EXPECT_TRUE(config_->ValidatePassphrase(&error, std::string(8, 'c')));
  EXPECT_TRUE(config_->ValidatePassphrase(&error, std::string(63, 'c')));
  EXPECT_FALSE(config_->ValidatePassphrase(&error, std::string(7, 'c')));
  EXPECT_FALSE(config_->ValidatePassphrase(&error, std::string(64, 'c')));
}

TEST_F(ConfigTest, ValidateHwMode) {
  Error error;
  EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211a));
  EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211b));
  EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211g));
  EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211n));
  EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211ac));
  EXPECT_FALSE(config_->ValidateSecurityMode(&error, "InvalidHwMode"));
}

TEST_F(ConfigTest, ValidateOperationMode) {
  Error error;
  EXPECT_TRUE(config_->ValidateOperationMode(&error, kOperationModeServer));
  EXPECT_TRUE(config_->ValidateOperationMode(&error, kOperationModeBridge));
  EXPECT_FALSE(config_->ValidateOperationMode(&error, "InvalidMode"));
}

TEST_F(ConfigTest, ValidateChannel) {
  Error error;
  EXPECT_TRUE(config_->ValidateChannel(&error, 1));
  EXPECT_TRUE(config_->ValidateChannel(&error, 13));
  EXPECT_TRUE(config_->ValidateChannel(&error, 34));
  EXPECT_TRUE(config_->ValidateChannel(&error, 165));
  EXPECT_FALSE(config_->ValidateChannel(&error, 0));
  EXPECT_FALSE(config_->ValidateChannel(&error, 14));
  EXPECT_FALSE(config_->ValidateChannel(&error, 33));
  EXPECT_FALSE(config_->ValidateChannel(&error, 166));
}

TEST_F(ConfigTest, NoSsid) {
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);

  std::string config_content;
  Error error;
  EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
  VerifyError(error, Error::kInvalidConfiguration, "SSID not specified");
}

TEST_F(ConfigTest, NoInterface) {
  // Basic 80211.g configuration.
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);

  // No device available, fail to generate config file.
  Error error;
  std::string config_content;
  EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(nullptr));
  EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
  VerifyError(error, Error::kInternalError, "No device available");
  Mock::VerifyAndClearExpectations(&manager_);

  // Device available, config file should be generated without any problem.
  scoped_refptr<MockDevice> device = new MockDevice(&manager_);
  device->SetPreferredApInterface(kInterface);
  error.Reset();
  EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(device));
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
  EXPECT_NE(std::string::npos, config_content.find(
                                   kExpected80211gConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211gConfigContent << "..within content...\n"
      << config_content;
  EXPECT_TRUE(error.IsSuccess());
  Mock::VerifyAndClearExpectations(&manager_);
}

TEST_F(ConfigTest, InvalidInterface) {
  // Basic 80211.g configuration.
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);

  // Unable to find the device, fail to generate config file.
  Error error;
  std::string config_content;
  EXPECT_CALL(manager_, GetDeviceFromInterfaceName(kInterface))
      .WillOnce(Return(nullptr));
  EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
  VerifyError(error,
              Error::kInvalidConfiguration,
              "Unable to find device for the specified interface");
  Mock::VerifyAndClearExpectations(&manager_);
}

TEST_F(ConfigTest, BridgeMode) {
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);
  config_->SetOperationMode(kOperationModeBridge);

  // Bridge interface required for bridge mode.
  Error error;
  std::string config_content;
  EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
  VerifyError(
      error, Error::kInvalidConfiguration, "Bridge interface not specified");

  // Set bridge interface, config file should be generated without error.
  config_->SetBridgeInterface(kBridgeInterface);
  // Setup mock device.
  SetupDevice(kInterface);
  error.Reset();
  std::string config_content1;
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content1));
  EXPECT_NE(std::string::npos, config_content1.find(
                                   kExpected80211gBridgeConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211gBridgeConfigContent << "..within content...\n"
      << config_content1;
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ConfigTest, 80211gConfig) {
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);

  // Setup mock device.
  SetupDevice(kInterface);

  std::string config_content;
  Error error;
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
  EXPECT_NE(std::string::npos, config_content.find(
                                   kExpected80211gConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211gConfigContent << "..within content...\n"
      << config_content;
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ConfigTest, 80211gConfigWithControlInterface) {
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);
  config_->set_control_interface(kControlInterfacePath);

  // Setup mock device.
  SetupDevice(kInterface);

  std::string config_content;
  Error error;
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
  EXPECT_NE(std::string::npos, config_content.find(
                                   kExpected80211gCtrlIfaceConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211gCtrlIfaceConfigContent << "..within content...\n"
      << config_content;
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ConfigTest, 80211nConfig) {
  config_->SetSsid(kSsid);
  config_->SetHwMode(kHwMode80211n);
  config_->SetInterfaceName(kInterface);

  // Setup mock device.
  SetupDevice(kInterface);

  // 5GHz channel.
  config_->SetChannel(k5GHzChannel);
  std::string ghz5_config_content;
  Error error;
  std::string ht_capab_5ghz(k5GHzHTCapab);
  EXPECT_CALL(*device_.get(), GetHTCapability(k5GHzChannel, _))
      .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_5ghz), Return(true)));
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &ghz5_config_content));
  EXPECT_NE(std::string::npos, ghz5_config_content.find(
                                   kExpected80211n5GHzConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211n5GHzConfigContent << "..within content...\n"
      << ghz5_config_content;
  EXPECT_TRUE(error.IsSuccess());
  Mock::VerifyAndClearExpectations(device_.get());

  // 2.4GHz channel.
  config_->SetChannel(k24GHzChannel);
  std::string ghz24_config_content;
  error.Reset();
  std::string ht_capab_24ghz(k24GHzHTCapab);
  EXPECT_CALL(*device_.get(), GetHTCapability(k24GHzChannel, _))
      .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_24ghz), Return(true)));
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &ghz24_config_content));
  EXPECT_NE(std::string::npos, ghz24_config_content.find(
                                   kExpected80211n24GHzConfigContent))
      << "Expected to find the following config...\n"
      << kExpected80211n24GHzConfigContent << "..within content...\n"
      << ghz24_config_content;
  EXPECT_TRUE(error.IsSuccess());
  Mock::VerifyAndClearExpectations(device_.get());
}

TEST_F(ConfigTest, RsnConfig) {
  config_->SetSsid(kSsid);
  config_->SetChannel(k24GHzChannel);
  config_->SetHwMode(kHwMode80211g);
  config_->SetInterfaceName(kInterface);
  config_->SetSecurityMode(kSecurityModeRSN);

  // Setup mock device.
  SetupDevice(kInterface);

  // Failed due to no passphrase specified.
  std::string config_content;
  Error error;
  EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
  VerifyError(
      error,
      Error::kInvalidConfiguration,
      base::StringPrintf("Passphrase not set for security mode: %s",
                         kSecurityModeRSN));

  error.Reset();
  config_->SetPassphrase(kPassphrase);
  EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
  EXPECT_NE(std::string::npos, config_content.find(
                                   kExpectedRsnConfigContent))
      << "Expected to find the following config...\n"
      << kExpectedRsnConfigContent << "..within content...\n"
      << config_content;
  EXPECT_TRUE(error.IsSuccess());
}

}  // namespace apmanager
