// Copyright (c) 2012 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 "chromeos/dbus/shill_manager_client.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/values.h"
#include "chromeos/dbus/shill_client_unittest_base.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/values_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using testing::_;
using testing::ByRef;

namespace chromeos {

namespace {

void ExpectThrottlingArguments(bool throttling_enabled_expected,
                               uint32_t upload_rate_kbits_expected,
                               uint32_t download_rate_kbits_expected,
                               dbus::MessageReader* reader) {
  bool throttling_enabled_actual;
  uint32_t upload_rate_kbits_actual;
  uint32_t download_rate_kbits_actual;
  ASSERT_TRUE(reader->PopBool(&throttling_enabled_actual));
  EXPECT_EQ(throttling_enabled_actual, throttling_enabled_expected);
  ASSERT_TRUE(reader->PopUint32(&upload_rate_kbits_actual));
  EXPECT_EQ(upload_rate_kbits_expected, upload_rate_kbits_actual);
  ASSERT_TRUE(reader->PopUint32(&download_rate_kbits_actual));
  EXPECT_EQ(download_rate_kbits_expected, download_rate_kbits_actual);
  EXPECT_FALSE(reader->HasMoreData());
}

}  // namespace

class ShillManagerClientTest : public ShillClientUnittestBase {
 public:
  ShillManagerClientTest()
      : ShillClientUnittestBase(shill::kFlimflamManagerInterface,
                                dbus::ObjectPath(shill::kFlimflamServicePath)) {
  }

  void SetUp() override {
    ShillClientUnittestBase::SetUp();
    // Create a client with the mock bus.
    client_.reset(ShillManagerClient::Create());
    client_->Init(mock_bus_.get());
    // Run the message loop to run the signal connection result callback.
    base::RunLoop().RunUntilIdle();
  }

 protected:
  std::unique_ptr<ShillManagerClient> client_;
};

TEST_F(ShillManagerClientTest, PropertyChanged) {
  // Create a signal.
  base::Value kOfflineMode(true);
  dbus::Signal signal(shill::kFlimflamManagerInterface,
                      shill::kMonitorPropertyChanged);
  dbus::MessageWriter writer(&signal);
  writer.AppendString(shill::kOfflineModeProperty);
  dbus::AppendBasicTypeValueData(&writer, kOfflineMode);

  // Set expectations.
  MockPropertyChangeObserver observer;
  EXPECT_CALL(observer,
              OnPropertyChanged(shill::kOfflineModeProperty,
                                ValueEq(ByRef(kOfflineMode)))).Times(1);

  // Add the observer
  client_->AddPropertyChangedObserver(&observer);

  // Run the signal callback.
  SendPropertyChangedSignal(&signal);

  // Remove the observer.
  client_->RemovePropertyChangedObserver(&observer);

  // Make sure it's not called anymore.
  EXPECT_CALL(observer, OnPropertyChanged(_, _)).Times(0);

  // Run the signal callback again and make sure the observer isn't called.
  SendPropertyChangedSignal(&signal);
}

TEST_F(ShillManagerClientTest, GetProperties) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  dbus::MessageWriter writer(response.get());
  dbus::MessageWriter array_writer(NULL);
  writer.OpenArray("{sv}", &array_writer);
  dbus::MessageWriter entry_writer(NULL);
  array_writer.OpenDictEntry(&entry_writer);
  entry_writer.AppendString(shill::kOfflineModeProperty);
  entry_writer.AppendVariantOfBool(true);
  array_writer.CloseContainer(&entry_writer);
  writer.CloseContainer(&array_writer);

  // Create the expected value.
  base::DictionaryValue value;
  value.SetKey(shill::kOfflineModeProperty, base::Value(true));
  // Set expectations.
  PrepareForMethodCall(shill::kGetPropertiesFunction,
                       base::Bind(&ExpectNoArgument),
                       response.get());
  // Call method.
  client_->GetProperties(base::Bind(&ExpectDictionaryValueResult, &value));
  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, GetNetworksForGeolocation) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());

  dbus::MessageWriter writer(response.get());
  dbus::MessageWriter type_dict_writer(NULL);
  writer.OpenArray("{sv}", &type_dict_writer);
  dbus::MessageWriter type_entry_writer(NULL);
  type_dict_writer.OpenDictEntry(&type_entry_writer);
  type_entry_writer.AppendString(shill::kTypeWifi);
  dbus::MessageWriter variant_writer(NULL);
  type_entry_writer.OpenVariant("aa{ss}", &variant_writer);
  dbus::MessageWriter wap_list_writer(NULL);
  variant_writer.OpenArray("a{ss}", &wap_list_writer);
  dbus::MessageWriter property_dict_writer(NULL);
  wap_list_writer.OpenArray("{ss}", &property_dict_writer);
  dbus::MessageWriter property_entry_writer(NULL);
  property_dict_writer.OpenDictEntry(&property_entry_writer);
  property_entry_writer.AppendString(shill::kGeoMacAddressProperty);
  property_entry_writer.AppendString("01:23:45:67:89:AB");
  property_dict_writer.CloseContainer(&property_entry_writer);
  wap_list_writer.CloseContainer(&property_dict_writer);
  variant_writer.CloseContainer(&wap_list_writer);
  type_entry_writer.CloseContainer(&wap_list_writer);
  type_dict_writer.CloseContainer(&type_entry_writer);
  writer.CloseContainer(&type_dict_writer);


  // Create the expected value.
  auto property_dict_value = std::make_unique<base::DictionaryValue>();
  property_dict_value->SetKey(shill::kGeoMacAddressProperty,
                              base::Value("01:23:45:67:89:AB"));
  auto type_entry_value = std::make_unique<base::ListValue>();
  type_entry_value->Append(std::move(property_dict_value));
  base::DictionaryValue type_dict_value;
  type_dict_value.SetWithoutPathExpansion("wifi", std::move(type_entry_value));

  // Set expectations.
  PrepareForMethodCall(shill::kGetNetworksForGeolocation,
                       base::Bind(&ExpectNoArgument),
                       response.get());
  // Call method.
  client_->GetNetworksForGeolocation(base::Bind(&ExpectDictionaryValueResult,
                                                &type_dict_value));

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, SetProperty) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  // Set expectations.
  base::Value value("portal list");
  PrepareForMethodCall(shill::kSetPropertyFunction,
                       base::Bind(ExpectStringAndValueArguments,
                                  shill::kCheckPortalListProperty,
                                  &value),
                       response.get());
  // Call method.
  base::MockCallback<base::Closure> mock_closure;
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->SetProperty(shill::kCheckPortalListProperty, value,
                       mock_closure.Get(), mock_error_callback.Get());
  EXPECT_CALL(mock_closure, Run()).Times(1);
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, RequestScan) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  // Set expectations.
  PrepareForMethodCall(shill::kRequestScanFunction,
                       base::Bind(&ExpectStringArgument, shill::kTypeWifi),
                       response.get());
  // Call method.
  base::MockCallback<base::Closure> mock_closure;
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->RequestScan(shill::kTypeWifi, mock_closure.Get(),
                       mock_error_callback.Get());
  EXPECT_CALL(mock_closure, Run()).Times(1);
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, EnableTechnology) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  // Set expectations.
  PrepareForMethodCall(shill::kEnableTechnologyFunction,
                       base::Bind(&ExpectStringArgument, shill::kTypeWifi),
                       response.get());
  // Call method.
  base::MockCallback<base::Closure> mock_closure;
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->EnableTechnology(shill::kTypeWifi, mock_closure.Get(),
                            mock_error_callback.Get());
  EXPECT_CALL(mock_closure, Run()).Times(1);
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, NetworkThrottling) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  // Set expectations.
  const bool enabled = true;
  const uint32_t upload_rate = 1200;
  const uint32_t download_rate = 2000;
  PrepareForMethodCall(shill::kSetNetworkThrottlingFunction,
                       base::Bind(&ExpectThrottlingArguments, enabled,
                                  upload_rate, download_rate),
                       response.get());
  // Call method.
  base::MockCallback<base::Closure> mock_closure;
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  EXPECT_CALL(mock_closure, Run()).Times(1);
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  client_->SetNetworkThrottlingStatus(
      ShillManagerClient::NetworkThrottlingStatus{enabled, upload_rate,
                                                  download_rate},
      mock_closure.Get(), mock_error_callback.Get());
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, DisableTechnology) {
  // Create response.
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  // Set expectations.
  PrepareForMethodCall(shill::kDisableTechnologyFunction,
                       base::Bind(&ExpectStringArgument, shill::kTypeWifi),
                       response.get());
  // Call method.
  base::MockCallback<base::Closure> mock_closure;
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->DisableTechnology(shill::kTypeWifi, mock_closure.Get(),
                             mock_error_callback.Get());
  EXPECT_CALL(mock_closure, Run()).Times(1);
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, ConfigureService) {
  // Create response.
  const dbus::ObjectPath object_path("/");
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  dbus::MessageWriter writer(response.get());
  writer.AppendObjectPath(object_path);
  // Create the argument dictionary.
  std::unique_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties());
  // Use a variant valued dictionary rather than a string valued one.
  const bool string_valued = false;
  // Set expectations.
  PrepareForMethodCall(
      shill::kConfigureServiceFunction,
      base::Bind(&ExpectDictionaryValueArgument, arg.get(), string_valued),
      response.get());
  // Call method.
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->ConfigureService(
      *arg, base::Bind(&ExpectObjectPathResultWithoutStatus, object_path),
      mock_error_callback.Get());
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ShillManagerClientTest, GetService) {
  // Create response.
  const dbus::ObjectPath object_path("/");
  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  dbus::MessageWriter writer(response.get());
  writer.AppendObjectPath(object_path);
  // Create the argument dictionary.
  std::unique_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties());
  // Use a variant valued dictionary rather than a string valued one.
  const bool string_valued = false;
  // Set expectations.
  PrepareForMethodCall(
      shill::kGetServiceFunction,
      base::Bind(&ExpectDictionaryValueArgument, arg.get(), string_valued),
      response.get());
  // Call method.
  base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
  client_->GetService(
      *arg, base::Bind(&ExpectObjectPathResultWithoutStatus, object_path),
      mock_error_callback.Get());
  EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);

  // Run the message loop.
  base::RunLoop().RunUntilIdle();
}

}  // namespace chromeos
