// 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 "chromeos/network/network_device_handler_impl.h"

#include <stddef.h>
#include <stdint.h>

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

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chromeos/dbus/shill/shill_device_client.h"
#include "chromeos/dbus/shill/shill_ipconfig_client.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state_handler.h"
#include "dbus/object_path.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

std::string GetErrorNameForShillError(const std::string& shill_error_name) {
  if (shill_error_name == shill::kErrorResultFailure ||
      shill_error_name == shill::kErrorResultInvalidArguments) {
    return NetworkDeviceHandler::kErrorFailure;
  }
  if (shill_error_name == shill::kErrorResultNotSupported)
    return NetworkDeviceHandler::kErrorNotSupported;
  if (shill_error_name == shill::kErrorResultIncorrectPin)
    return NetworkDeviceHandler::kErrorIncorrectPin;
  if (shill_error_name == shill::kErrorResultPinBlocked)
    return NetworkDeviceHandler::kErrorPinBlocked;
  if (shill_error_name == shill::kErrorResultPinRequired)
    return NetworkDeviceHandler::kErrorPinRequired;
  if (shill_error_name == shill::kErrorResultNotFound)
    return NetworkDeviceHandler::kErrorDeviceMissing;
  return NetworkDeviceHandler::kErrorUnknown;
}

void GetPropertiesCallback(const std::string& device_path,
                           network_handler::ResultCallback callback,
                           base::Optional<base::Value> result) {
  if (!result) {
    NET_LOG(ERROR) << "GetProperties failed: " << NetworkPathId(device_path);
    std::move(callback).Run(device_path, base::nullopt);
    return;
  }
  std::move(callback).Run(device_path, std::move(result));
}

void InvokeErrorCallback(const std::string& device_path,
                         network_handler::ErrorCallback error_callback,
                         const std::string& error_name) {
  std::string error_msg = "Device Error: " + error_name;
  NET_LOG(ERROR) << error_msg << ": " << device_path;
  network_handler::RunErrorCallback(std::move(error_callback), device_path,
                                    error_name, error_msg);
}

void HandleShillCallFailure(const std::string& device_path,
                            network_handler::ErrorCallback error_callback,
                            const std::string& shill_error_name,
                            const std::string& shill_error_message) {
  network_handler::ShillErrorCallbackFunction(
      GetErrorNameForShillError(shill_error_name), device_path,
      std::move(error_callback), shill_error_name, shill_error_message);
}

void SetDevicePropertyInternal(const std::string& device_path,
                               const std::string& property_name,
                               const base::Value& value,
                               base::OnceClosure callback,
                               network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.SetProperty: " << property_name << " = " << value;
  ShillDeviceClient::Get()->SetProperty(
      dbus::ObjectPath(device_path), property_name, value, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

std::unique_ptr<base::DictionaryValue> GetErrorData(const std::string& name) {
  auto error_data = std::make_unique<base::DictionaryValue>();
  error_data->SetString(network_handler::kErrorName, name);
  return error_data;
}

}  // namespace

NetworkDeviceHandlerImpl::NetworkDeviceHandlerImpl() = default;

NetworkDeviceHandlerImpl::~NetworkDeviceHandlerImpl() {
  if (network_state_handler_)
    network_state_handler_->RemoveObserver(this, FROM_HERE);
}

void NetworkDeviceHandlerImpl::GetDeviceProperties(
    const std::string& device_path,
    network_handler::ResultCallback callback) const {
  ShillDeviceClient::Get()->GetProperties(
      dbus::ObjectPath(device_path),
      base::BindOnce(&GetPropertiesCallback, device_path, std::move(callback)));
}

void NetworkDeviceHandlerImpl::SetDeviceProperty(
    const std::string& device_path,
    const std::string& property_name,
    const base::Value& value,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const char* const property_blocked[] = {
      // Must only be changed by policy/owner through.
      shill::kCellularAllowRoamingProperty};

  for (size_t i = 0; i < base::size(property_blocked); ++i) {
    if (property_name == property_blocked[i]) {
      InvokeErrorCallback(
          device_path, std::move(error_callback),
          "SetDeviceProperty called on blocked property " + property_name);
      return;
    }
  }

  SetDevicePropertyInternal(device_path, property_name, value,
                            std::move(callback), std::move(error_callback));
}

void NetworkDeviceHandlerImpl::RegisterCellularNetwork(
    const std::string& device_path,
    const std::string& network_id,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.RegisterCellularNetwork: " << device_path
                << " Id: " << network_id;
  ShillDeviceClient::Get()->Register(
      dbus::ObjectPath(device_path), network_id, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::RequirePin(
    const std::string& device_path,
    bool require_pin,
    const std::string& pin,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.RequirePin: " << device_path << ": " << require_pin;
  ShillDeviceClient::Get()->RequirePin(
      dbus::ObjectPath(device_path), pin, require_pin, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::EnterPin(
    const std::string& device_path,
    const std::string& pin,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.EnterPin: " << device_path;
  ShillDeviceClient::Get()->EnterPin(
      dbus::ObjectPath(device_path), pin, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::UnblockPin(
    const std::string& device_path,
    const std::string& puk,
    const std::string& new_pin,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.UnblockPin: " << device_path;
  ShillDeviceClient::Get()->UnblockPin(
      dbus::ObjectPath(device_path), puk, new_pin, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::ChangePin(
    const std::string& device_path,
    const std::string& old_pin,
    const std::string& new_pin,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  NET_LOG(USER) << "Device.ChangePin: " << device_path;
  ShillDeviceClient::Get()->ChangePin(
      dbus::ObjectPath(device_path), old_pin, new_pin, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_path,
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::SetCellularAllowRoaming(
    const bool allow_roaming) {
  cellular_allow_roaming_ = allow_roaming;
  ApplyCellularAllowRoamingToShill();
}

void NetworkDeviceHandlerImpl::SetMACAddressRandomizationEnabled(
    const bool enabled) {
  mac_addr_randomization_enabled_ = enabled;
  ApplyMACAddressRandomizationToShill();
}

void NetworkDeviceHandlerImpl::SetUsbEthernetMacAddressSource(
    const std::string& source) {
  if (source == usb_ethernet_mac_address_source_) {
    return;
  }

  usb_ethernet_mac_address_source_ = source;
  mac_address_change_not_supported_.clear();
  ApplyUsbEthernetMacAddressSourceToShill();
}

void NetworkDeviceHandlerImpl::AddWifiWakeOnPacketConnection(
    const net::IPEndPoint& ip_endpoint,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    if (error_callback) {
      std::move(error_callback)
          .Run(kErrorDeviceMissing, GetErrorData(kErrorDeviceMissing));
    }
    return;
  }

  NET_LOG(USER) << "Device.AddWakeOnWifi: " << device_state->path();
  ShillDeviceClient::Get()->AddWakeOnPacketConnection(
      dbus::ObjectPath(device_state->path()), ip_endpoint, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_state->path(),
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::AddWifiWakeOnPacketOfTypes(
    const std::vector<std::string>& types,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    if (error_callback) {
      std::move(error_callback)
          .Run(kErrorDeviceMissing, GetErrorData(kErrorDeviceMissing));
    }
    return;
  }

  NET_LOG(USER) << "Device.AddWifiWakeOnPacketOfTypes: " << device_state->path()
                << " Types: " << base::JoinString(types, " ");
  ShillDeviceClient::Get()->AddWakeOnPacketOfTypes(
      dbus::ObjectPath(device_state->path()), types, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_state->path(),
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::RemoveWifiWakeOnPacketConnection(
    const net::IPEndPoint& ip_endpoint,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    if (error_callback) {
      std::move(error_callback)
          .Run(kErrorDeviceMissing, GetErrorData(kErrorDeviceMissing));
    }
    return;
  }

  NET_LOG(USER) << "Device.RemoveWakeOnWifi: " << device_state->path();
  ShillDeviceClient::Get()->RemoveWakeOnPacketConnection(
      dbus::ObjectPath(device_state->path()), ip_endpoint, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_state->path(),
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::RemoveWifiWakeOnPacketOfTypes(
    const std::vector<std::string>& types,
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    if (error_callback) {
      std::move(error_callback)
          .Run(kErrorDeviceMissing, GetErrorData(kErrorDeviceMissing));
    }
    return;
  }

  NET_LOG(USER) << "Device.RemoveWifiWakeOnPacketOfTypes: "
                << device_state->path()
                << " Types: " << base::JoinString(types, " ");
  ShillDeviceClient::Get()->RemoveWakeOnPacketOfTypes(
      dbus::ObjectPath(device_state->path()), types, std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_state->path(),
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::RemoveAllWifiWakeOnPacketConnections(
    base::OnceClosure callback,
    network_handler::ErrorCallback error_callback) {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    if (error_callback) {
      std::move(error_callback)
          .Run(kErrorDeviceMissing, GetErrorData(kErrorDeviceMissing));
    }
    return;
  }

  NET_LOG(USER) << "Device.RemoveAllWakeOnWifi: " << device_state->path();
  ShillDeviceClient::Get()->RemoveAllWakeOnPacketConnections(
      dbus::ObjectPath(device_state->path()), std::move(callback),
      base::BindOnce(&HandleShillCallFailure, device_state->path(),
                     std::move(error_callback)));
}

void NetworkDeviceHandlerImpl::DeviceListChanged() {
  ApplyCellularAllowRoamingToShill();
  ApplyMACAddressRandomizationToShill();
  ApplyUsbEthernetMacAddressSourceToShill();
}

void NetworkDeviceHandlerImpl::DevicePropertiesUpdated(
    const DeviceState* device) {
  ApplyUsbEthernetMacAddressSourceToShill();
}

void NetworkDeviceHandlerImpl::Init(
    NetworkStateHandler* network_state_handler) {
  DCHECK(network_state_handler);
  network_state_handler_ = network_state_handler;
  network_state_handler_->AddObserver(this, FROM_HERE);
}

void NetworkDeviceHandlerImpl::ApplyCellularAllowRoamingToShill() {
  NetworkStateHandler::DeviceStateList list;
  network_state_handler_->GetDeviceListByType(NetworkTypePattern::Cellular(),
                                              &list);
  if (list.empty()) {
    NET_LOG(DEBUG) << "No cellular device available. Roaming is only supported "
                      "by cellular devices.";
    return;
  }
  for (NetworkStateHandler::DeviceStateList::const_iterator it = list.begin();
       it != list.end(); ++it) {
    const DeviceState* device_state = *it;
    bool current_allow_roaming = device_state->allow_roaming();

    // If roaming is required by the provider, always try to set to true.
    bool new_device_value =
        device_state->provider_requires_roaming() || cellular_allow_roaming_;

    // Only set the value if the current value is different from
    // |new_device_value|.
    if (new_device_value == current_allow_roaming)
      continue;

    SetDevicePropertyInternal(device_state->path(),
                              shill::kCellularAllowRoamingProperty,
                              base::Value(new_device_value), base::DoNothing(),
                              network_handler::ErrorCallback());
  }
}

void NetworkDeviceHandlerImpl::ApplyMACAddressRandomizationToShill() {
  const DeviceState* device_state = GetWifiDeviceState();
  if (!device_state) {
    // We'll need to ask if this is supported when we find a Wi-Fi
    // device.
    mac_addr_randomization_supported_ =
        MACAddressRandomizationSupport::NOT_REQUESTED;
    return;
  }

  switch (mac_addr_randomization_supported_) {
    case MACAddressRandomizationSupport::NOT_REQUESTED:
      GetDeviceProperties(
          device_state->path(),
          base::BindOnce(
              &NetworkDeviceHandlerImpl::HandleMACAddressRandomization,
              weak_ptr_factory_.GetWeakPtr()));
      return;
    case MACAddressRandomizationSupport::SUPPORTED:
      SetDevicePropertyInternal(
          device_state->path(), shill::kMacAddressRandomizationEnabledProperty,
          base::Value(mac_addr_randomization_enabled_), base::DoNothing(),
          network_handler::ErrorCallback());
      return;
    case MACAddressRandomizationSupport::UNSUPPORTED:
      return;
  }
}

void NetworkDeviceHandlerImpl::ApplyUsbEthernetMacAddressSourceToShill() {
  // Do nothing else if MAC address source is not specified yet.
  if (usb_ethernet_mac_address_source_.empty()) {
    NET_LOG(DEBUG) << "Empty USB Ethernet MAC address source.";
    return;
  }

  UpdatePrimaryEnabledUsbEthernetDevice();
  ResetMacAddressSourceForSecondaryUsbEthernetDevices();

  const DeviceState* primary_enabled_usb_ethernet_device_state =
      network_state_handler_->GetDeviceState(
          primary_enabled_usb_ethernet_device_path_);

  // Do nothing else if device path is empty or device state is nullptr or
  // device MAC address source property equals to needed value.
  if (primary_enabled_usb_ethernet_device_path_.empty() ||
      !primary_enabled_usb_ethernet_device_state ||
      primary_enabled_usb_ethernet_device_state->mac_address_source() ==
          usb_ethernet_mac_address_source_) {
    return;
  }

  ShillDeviceClient::Get()->SetUsbEthernetMacAddressSource(
      dbus::ObjectPath(primary_enabled_usb_ethernet_device_path_),
      usb_ethernet_mac_address_source_, base::DoNothing(),
      base::BindOnce(
          &NetworkDeviceHandlerImpl::OnSetUsbEthernetMacAddressSourceError,
          weak_ptr_factory_.GetWeakPtr(),
          primary_enabled_usb_ethernet_device_path_,
          primary_enabled_usb_ethernet_device_state->mac_address(),
          usb_ethernet_mac_address_source_, network_handler::ErrorCallback()));
}

void NetworkDeviceHandlerImpl::OnSetUsbEthernetMacAddressSourceError(
    const std::string& device_path,
    const std::string& device_mac_address,
    const std::string& mac_address_source,
    network_handler::ErrorCallback error_callback,
    const std::string& shill_error_name,
    const std::string& shill_error_message) {
  HandleShillCallFailure(device_path, std::move(error_callback),
                         shill_error_name, shill_error_message);
  if (shill_error_name == shill::kErrorResultNotSupported &&
      mac_address_source == usb_ethernet_mac_address_source_) {
    mac_address_change_not_supported_.insert(device_mac_address);
    ApplyUsbEthernetMacAddressSourceToShill();
  }
}

bool NetworkDeviceHandlerImpl::IsUsbEnabledDevice(
    const DeviceState* device_state) const {
  return device_state && device_state->link_up() &&
         device_state->Matches(NetworkTypePattern::Ethernet()) &&
         device_state->device_bus_type() == shill::kDeviceBusTypeUsb &&
         mac_address_change_not_supported_.find(device_state->mac_address()) ==
             mac_address_change_not_supported_.end();
}

void NetworkDeviceHandlerImpl::UpdatePrimaryEnabledUsbEthernetDevice() {
  NetworkStateHandler::DeviceStateList device_state_list;
  network_state_handler_->GetDeviceListByType(NetworkTypePattern::Ethernet(),
                                              &device_state_list);

  // Try to avoid situation when both PCI and USB Ethernet devices are enabled
  // and have the same MAC address. In this situation we will change back USB
  // Ethernet MAC address.
  if (usb_ethernet_mac_address_source_ ==
      shill::kUsbEthernetMacAddressSourceBuiltinAdapterMac) {
    for (const auto* device_state : device_state_list) {
      if (device_state && device_state->link_up() &&
          device_state->device_bus_type() == shill::kDeviceBusTypePci) {
        primary_enabled_usb_ethernet_device_path_ = "";
        return;
      }
    }
  }

  // Nothing change, primary USB Ethernet device still enabled.
  // Note that if |primary_enabled_usb_ethernet_device_path_| is empty, this
  // will be IsUsbEnabledDevice(nullptr) which returns false.
  if (IsUsbEnabledDevice(network_state_handler_->GetDeviceState(
          primary_enabled_usb_ethernet_device_path_))) {
    return;
  }

  // Reset primary enabled USB Ethernet device since it isn't enabled anymore.
  primary_enabled_usb_ethernet_device_path_ = "";

  // Give the priority to USB Ethernet device which already has the required MAC
  // address source property. It can happen after Chrome crashes, when shill
  // devices have some properties and Chrome does not know which device was
  // the primary USB Ethernet before the crash.
  for (const auto* device_state : device_state_list) {
    if (IsUsbEnabledDevice(device_state) && device_state &&
        device_state->mac_address_source() ==
            usb_ethernet_mac_address_source_) {
      primary_enabled_usb_ethernet_device_path_ = device_state->path();
      return;
    }
  }

  for (const auto* device_state : device_state_list) {
    if (IsUsbEnabledDevice(device_state)) {
      primary_enabled_usb_ethernet_device_path_ = device_state->path();
      return;
    }
  }
}

void NetworkDeviceHandlerImpl::
    ResetMacAddressSourceForSecondaryUsbEthernetDevices() const {
  NetworkStateHandler::DeviceStateList device_state_list;
  network_state_handler_->GetDeviceListByType(NetworkTypePattern::Ethernet(),
                                              &device_state_list);

  for (const auto* device_state : device_state_list) {
    if (!device_state ||
        device_state->path() == primary_enabled_usb_ethernet_device_path_ ||
        device_state->mac_address_source().empty() ||
        device_state->mac_address_source() ==
            shill::kUsbEthernetMacAddressSourceUsbAdapterMac) {
      continue;
    }
    ShillDeviceClient::Get()->SetUsbEthernetMacAddressSource(
        dbus::ObjectPath(device_state->path()),
        shill::kUsbEthernetMacAddressSourceUsbAdapterMac, base::DoNothing(),
        base::BindOnce(&HandleShillCallFailure, device_state->path(),
                       network_handler::ErrorCallback()));
  }
}

void NetworkDeviceHandlerImpl::HandleMACAddressRandomization(
    const std::string& device_path,
    base::Optional<base::Value> properties) {
  if (!properties)
    return;
  base::Optional<bool> supported =
      properties->FindBoolKey(shill::kMacAddressRandomizationSupportedProperty);
  if (!supported.has_value()) {
    if (base::SysInfo::IsRunningOnChromeOS()) {
      NET_LOG(ERROR) << "Failed to determine if device " << device_path
                     << " supports MAC address randomization";
    }
    return;
  }

  // Try to set MAC address randomization if it's supported.
  if (*supported) {
    mac_addr_randomization_supported_ =
        MACAddressRandomizationSupport::SUPPORTED;
    ApplyMACAddressRandomizationToShill();
  } else {
    mac_addr_randomization_supported_ =
        MACAddressRandomizationSupport::UNSUPPORTED;
  }
}

const DeviceState* NetworkDeviceHandlerImpl::GetWifiDeviceState() {
  return network_state_handler_->GetDeviceStateByType(
      NetworkTypePattern::WiFi());
}

}  // namespace chromeos
