// Copyright 2014 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/network/host_resolver_impl_chromeos.h"

#include "base/location.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_device_client.h"
#include "chromeos/dbus/shill_ipconfig_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "dbus/object_path.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace {

const char kTestIPv4Address[] = "1.2.3.4";
const char kTestIPv6Address[] = "1:2:3:4:5:6:7:8";

void DoNothingWithCallStatus(chromeos::DBusMethodCallStatus call_status) {}
void ErrorCallbackFunction(const std::string& error_name,
                           const std::string& error_message) {
  LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
}
void ResolveCompletionCallback(int result) {}

}  // namespace

class HostResolverImplChromeOSTest : public testing::Test {
 public:
  HostResolverImplChromeOSTest() {}

  ~HostResolverImplChromeOSTest() override {}

  void SetUp() override {
    chromeos::DBusThreadManager::Initialize();

    network_state_handler_.reset(
        chromeos::NetworkStateHandler::InitializeForTest());
    base::RunLoop().RunUntilIdle();

    const chromeos::NetworkState* default_network =
        network_state_handler_->DefaultNetwork();
    ASSERT_TRUE(default_network);
    const chromeos::DeviceState* default_device =
        network_state_handler_->GetDeviceState(default_network->device_path());
    ASSERT_TRUE(default_device);
    SetDefaultIPConfigs(default_device->path());

    // Create the host resolver from the IO message loop.
    io_message_loop_.PostTask(
        FROM_HERE,
        base::Bind(&HostResolverImplChromeOSTest::InitializeHostResolver,
                   base::Unretained(this)));
    io_message_loop_.RunUntilIdle();

    // Run the main message loop to create the network observer and initialize
    // the ip address values.
    base::RunLoop().RunUntilIdle();
  }

  void TearDown() override {
    network_state_handler_.reset();
    chromeos::DBusThreadManager::Shutdown();
  }

 protected:
  // Run from main (UI) message loop, calls Resolve on IO message loop.
  int CallResolve(net::HostResolver::RequestInfo& info) {
    io_message_loop_.task_runner()->PostTask(
        FROM_HERE, base::Bind(&HostResolverImplChromeOSTest::Resolve,
                              base::Unretained(this), info));
    io_message_loop_.RunUntilIdle();
    return result_;
  }

  net::AddressList addresses_;
  int result_;

 private:
  // Run from IO message loop.
  void InitializeHostResolver() {
    net::HostResolver::Options options;
    host_resolver_ =
        chromeos::HostResolverImplChromeOS::CreateHostResolverForTest(
            base::ThreadTaskRunnerHandle::Get(), network_state_handler_.get());
  }

  // Run from IO message loop.
  void Resolve(net::HostResolver::RequestInfo info) {
    result_ = host_resolver_->Resolve(
        info,
        net::DEFAULT_PRIORITY,
        &addresses_,
        base::Bind(&ResolveCompletionCallback),
        NULL,
        net_log_);
  }

  void SetDefaultIPConfigs(const std::string& default_device_path) {
    const std::string kTestIPv4ConfigPath("test_ip_v4_config_path");
    const std::string kTestIPv6ConfigPath("test_ip_v6_config_path");

    SetIPConfig(kTestIPv4ConfigPath, shill::kTypeIPv4, kTestIPv4Address);
    SetIPConfig(kTestIPv6ConfigPath, shill::kTypeIPv6, kTestIPv6Address);
    base::RunLoop().RunUntilIdle();

    base::ListValue ip_configs;
    ip_configs.AppendString(kTestIPv4ConfigPath);
    ip_configs.AppendString(kTestIPv6ConfigPath);

    chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
        dbus::ObjectPath(default_device_path),
        shill::kIPConfigsProperty,
        ip_configs,
        base::Bind(&base::DoNothing),
        base::Bind(&ErrorCallbackFunction));
    base::RunLoop().RunUntilIdle();
  }

  void SetIPConfig(const std::string& path,
                   const std::string& method,
                   const std::string& address) {
    chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
        dbus::ObjectPath(path),
        shill::kAddressProperty,
        base::StringValue(address),
        base::Bind(&DoNothingWithCallStatus));
    chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
        dbus::ObjectPath(path),
        shill::kMethodProperty,
        base::StringValue(method),
        base::Bind(&DoNothingWithCallStatus));
  }

  scoped_ptr<chromeos::NetworkStateHandler> network_state_handler_;
  scoped_ptr<net::HostResolver> host_resolver_;
  base::MessageLoop io_message_loop_;
  net::BoundNetLog net_log_;

  DISALLOW_COPY_AND_ASSIGN(HostResolverImplChromeOSTest);
};

TEST_F(HostResolverImplChromeOSTest, Resolve) {
  net::HostResolver::RequestInfo info(
      net::HostPortPair(net::GetHostName(), 80));
  info.set_address_family(net::ADDRESS_FAMILY_IPV4);
  info.set_is_my_ip_address(true);
  EXPECT_EQ(net::OK, CallResolve(info));
  ASSERT_EQ(1u, addresses_.size());
  std::string expected = base::StringPrintf("%s:%d", kTestIPv4Address, 0);
  EXPECT_EQ(expected, addresses_[0].ToString());

  info.set_address_family(net::ADDRESS_FAMILY_IPV6);
  EXPECT_EQ(net::OK, CallResolve(info));
  ASSERT_EQ(2u, addresses_.size());
  expected = base::StringPrintf("[%s]:%d", kTestIPv6Address, 0);
  EXPECT_EQ(expected, addresses_[0].ToString());
  expected = base::StringPrintf("%s:%d", kTestIPv4Address, 0);
  EXPECT_EQ(expected, addresses_[1].ToString());
}
