// Copyright 2013 The Chromium 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 <memory>

#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/values.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_shill_device_client.h"
#include "chromeos/dbus/fake_shill_manager_client.h"
#include "chromeos/network/network_device_handler_impl.h"
#include "chromeos/network/network_state_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

const char kDefaultCellularDevicePath[] = "stub_cellular_device";
const char kUnknownCellularDevicePath[] = "unknown_cellular_device";
const char kDefaultWifiDevicePath[] = "stub_wifi_device";
const char kResultSuccess[] = "success";
const char kDefaultPin[] = "1111";

}  // namespace

class NetworkDeviceHandlerTest : public testing::Test {
 public:
  NetworkDeviceHandlerTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
  ~NetworkDeviceHandlerTest() override {}

  void SetUp() override {
    fake_device_client_ = new FakeShillDeviceClient;
    DBusThreadManager::GetSetterForTesting()->SetShillDeviceClient(
        std::unique_ptr<ShillDeviceClient>(fake_device_client_));

    success_callback_ = base::Bind(&NetworkDeviceHandlerTest::SuccessCallback,
                                   base::Unretained(this));
    properties_success_callback_ =
        base::Bind(&NetworkDeviceHandlerTest::PropertiesSuccessCallback,
                   base::Unretained(this));
    string_success_callback_ =
        base::Bind(&NetworkDeviceHandlerTest::StringSuccessCallback,
                   base::Unretained(this));
    error_callback_ = base::Bind(&NetworkDeviceHandlerTest::ErrorCallback,
                                 base::Unretained(this));

    network_state_handler_ = NetworkStateHandler::InitializeForTest();
    NetworkDeviceHandlerImpl* device_handler = new NetworkDeviceHandlerImpl;
    device_handler->Init(network_state_handler_.get());
    network_device_handler_.reset(device_handler);

    // Add devices after handlers have been initialized.
    ShillDeviceClient::TestInterface* device_test =
        fake_device_client_->GetTestInterface();
    device_test->AddDevice(
        kDefaultCellularDevicePath, shill::kTypeCellular, "cellular1");
    device_test->AddDevice(kDefaultWifiDevicePath, shill::kTypeWifi, "wifi1");

    base::ListValue test_ip_configs;
    test_ip_configs.AppendString("ip_config1");
    device_test->SetDeviceProperty(
        kDefaultWifiDevicePath, shill::kIPConfigsProperty, test_ip_configs);

    base::RunLoop().RunUntilIdle();
  }

  void TearDown() override {
    network_state_handler_->Shutdown();
    network_device_handler_.reset();
    network_state_handler_.reset();
    DBusThreadManager::Shutdown();
  }

  void ErrorCallback(const std::string& error_name,
                     std::unique_ptr<base::DictionaryValue> error_data) {
    VLOG(1) << "ErrorCallback: " << error_name;
    result_ = error_name;
  }

  void SuccessCallback() {
    result_ = kResultSuccess;
  }

  void PropertiesSuccessCallback(const std::string& device_path,
                                 const base::DictionaryValue& properties) {
    result_ = kResultSuccess;
    properties_.reset(properties.DeepCopy());
  }

  void StringSuccessCallback(const std::string& result) {
    VLOG(1) << "StringSuccessCallback: " << result;
    result_ = result;
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::string result_;
  FakeShillDeviceClient* fake_device_client_ = nullptr;
  std::unique_ptr<NetworkDeviceHandler> network_device_handler_;
  std::unique_ptr<NetworkStateHandler> network_state_handler_;
  base::Closure success_callback_;
  network_handler::DictionaryResultCallback properties_success_callback_;
  network_handler::StringResultCallback string_success_callback_;
  network_handler::ErrorCallback error_callback_;
  std::unique_ptr<base::DictionaryValue> properties_;

 private:
  DISALLOW_COPY_AND_ASSIGN(NetworkDeviceHandlerTest);
};

TEST_F(NetworkDeviceHandlerTest, GetDeviceProperties) {
  network_device_handler_->GetDeviceProperties(
      kDefaultWifiDevicePath, properties_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  std::string type;
  properties_->GetString(shill::kTypeProperty, &type);
  EXPECT_EQ(shill::kTypeWifi, type);
}

TEST_F(NetworkDeviceHandlerTest, SetDeviceProperty) {
  // Set the shill::kScanIntervalProperty to true. The call
  // should succeed and the value should be set.
  network_device_handler_->SetDeviceProperty(
      kDefaultCellularDevicePath, shill::kScanIntervalProperty, base::Value(1),
      success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // GetDeviceProperties should return the value set by SetDeviceProperty.
  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
                                               properties_success_callback_,
                                               error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  int interval = 0;
  EXPECT_TRUE(properties_->GetIntegerWithoutPathExpansion(
      shill::kScanIntervalProperty, &interval));
  EXPECT_EQ(1, interval);

  // Repeat the same with value false.
  network_device_handler_->SetDeviceProperty(
      kDefaultCellularDevicePath, shill::kScanIntervalProperty, base::Value(2),
      success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
                                               properties_success_callback_,
                                               error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  EXPECT_TRUE(properties_->GetIntegerWithoutPathExpansion(
      shill::kScanIntervalProperty, &interval));
  EXPECT_EQ(2, interval);

  // Set property on an invalid path.
  network_device_handler_->SetDeviceProperty(
      kUnknownCellularDevicePath, shill::kScanIntervalProperty, base::Value(1),
      success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);

  // Setting a owner-protected device property through SetDeviceProperty must
  // fail.
  network_device_handler_->SetDeviceProperty(
      kDefaultCellularDevicePath, shill::kCellularAllowRoamingProperty,
      base::Value(true), success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_NE(kResultSuccess, result_);
}

TEST_F(NetworkDeviceHandlerTest, CellularAllowRoaming) {
  // Start with disabled data roaming.
  ShillDeviceClient::TestInterface* device_test =
      fake_device_client_->GetTestInterface();
  device_test->SetDeviceProperty(kDefaultCellularDevicePath,
                                 shill::kCellularAllowRoamingProperty,
                                 base::Value(false));

  network_device_handler_->SetCellularAllowRoaming(true);
  base::RunLoop().RunUntilIdle();

  // Roaming should be enabled now.
  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
                                               properties_success_callback_,
                                               error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  bool allow_roaming;
  EXPECT_TRUE(properties_->GetBooleanWithoutPathExpansion(
      shill::kCellularAllowRoamingProperty, &allow_roaming));
  EXPECT_TRUE(allow_roaming);

  network_device_handler_->SetCellularAllowRoaming(false);
  base::RunLoop().RunUntilIdle();

  // Roaming should be disable again.
  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
                                               properties_success_callback_,
                                               error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  EXPECT_TRUE(properties_->GetBooleanWithoutPathExpansion(
      shill::kCellularAllowRoamingProperty, &allow_roaming));
  EXPECT_FALSE(allow_roaming);
}

TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabled) {
  // We add a wifi device by default, initial call should succeed.
  fake_device_client_->GetTestInterface()->SetTDLSState(
      shill::kTDLSConnectedState);
  network_device_handler_->SetWifiTDLSEnabled(
      "fake_ip_address", true, string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kTDLSConnectedState, result_);
}

TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabledNonexistent) {
  // Set the TDLS state to 'Nonexistant'. Call should fail with 'Nonexistant'
  // result.
  fake_device_client_->GetTestInterface()->SetTDLSState(
      shill::kTDLSNonexistentState);
  network_device_handler_->SetWifiTDLSEnabled(
      "fake_ip_address", true, string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kTDLSNonexistentState, result_);
}

TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabledMissing) {
  // Remove the wifi device. Call should fail with "device missing" error.
  fake_device_client_->GetTestInterface()->RemoveDevice(kDefaultWifiDevicePath);
  base::RunLoop().RunUntilIdle();
  network_device_handler_->SetWifiTDLSEnabled(
      "fake_ip_address", true, string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabledBusy) {
  // Set the busy count, call should succeed after repeat attempt.
  fake_device_client_->GetTestInterface()->SetTDLSState(
      shill::kTDLSConnectedState);
  fake_device_client_->GetTestInterface()->SetTDLSBusyCount(1);
  network_device_handler_->SetWifiTDLSEnabled(
      "fake_ip_address", true, string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kTDLSConnectedState, result_);

  // Set the busy count to a large number, call should fail after max number
  // of repeat attempt.
  fake_device_client_->GetTestInterface()->SetTDLSBusyCount(100000);
  network_device_handler_->SetWifiTDLSEnabled(
      "fake_ip_address", true, string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorTimeout, result_);
}

TEST_F(NetworkDeviceHandlerTest, GetWifiTDLSStatus) {
  // We add a wifi device by default, initial call should succeed.
  fake_device_client_->GetTestInterface()->SetTDLSState(
      shill::kTDLSConnectedState);
  network_device_handler_->GetWifiTDLSStatus(
      "fake_ip_address", string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kTDLSConnectedState, result_);

  // Remove the wifi device. Call should fail with "device missing" error.
  fake_device_client_->GetTestInterface()->RemoveDevice(kDefaultWifiDevicePath);
  base::RunLoop().RunUntilIdle();
  network_device_handler_->GetWifiTDLSStatus(
      "fake_ip_address", string_success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, RequestRefreshIPConfigs) {
  network_device_handler_->RequestRefreshIPConfigs(
      kDefaultWifiDevicePath, success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);
  // TODO(stevenjb): Add test interface to ShillIPConfigClient and test
  // refresh calls.
}

TEST_F(NetworkDeviceHandlerTest, SetCarrier) {
  const char kCarrier[] = "carrier";

  // Test that the success callback gets called.
  network_device_handler_->SetCarrier(
      kDefaultCellularDevicePath, kCarrier, success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // Test that the shill error propagates to the error callback.
  network_device_handler_->SetCarrier(
      kUnknownCellularDevicePath, kCarrier, success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, RequirePin) {
  // Test that the success callback gets called.
  network_device_handler_->RequirePin(kDefaultCellularDevicePath,
                                      true,
                                      kDefaultPin,
                                      success_callback_,
                                      error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // Test that the shill error propagates to the error callback.
  network_device_handler_->RequirePin(kUnknownCellularDevicePath,
                                      true,
                                      kDefaultPin,
                                      success_callback_,
                                      error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, EnterPin) {
  // Test that the success callback gets called.
  network_device_handler_->EnterPin(kDefaultCellularDevicePath,
                                    kDefaultPin,
                                    success_callback_,
                                    error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // Test that the shill error propagates to the error callback.
  network_device_handler_->EnterPin(kUnknownCellularDevicePath,
                                    kDefaultPin,
                                    success_callback_,
                                    error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, UnblockPin) {
  const char kPuk[] = "12345678";
  const char kPin[] = "1234";

  // Test that the success callback gets called.
  network_device_handler_->UnblockPin(kDefaultCellularDevicePath,
                                      kPin,
                                      kPuk,
                                      success_callback_,
                                      error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // Test that the shill error propagates to the error callback.
  network_device_handler_->UnblockPin(kUnknownCellularDevicePath,
                                      kPin,
                                      kPuk,
                                      success_callback_,
                                      error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
}

TEST_F(NetworkDeviceHandlerTest, ChangePin) {
  const char kNewPin[] = "1234";
  const char kIncorrectPin[] = "9999";

  fake_device_client_->SetSimLocked(kDefaultCellularDevicePath, true);

  // Test that the success callback gets called.
  network_device_handler_->ChangePin(
      kDefaultCellularDevicePath, FakeShillDeviceClient::kDefaultSimPin,
      kNewPin, success_callback_, error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kResultSuccess, result_);

  // Test that the shill error propagates to the error callback.
  network_device_handler_->ChangePin(kDefaultCellularDevicePath, kIncorrectPin,
                                     kNewPin, success_callback_,
                                     error_callback_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NetworkDeviceHandler::kErrorIncorrectPin, result_);
}

}  // namespace chromeos
