// 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(&variant_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
