// Copyright 2017 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 "net/base/network_interfaces_fuchsia.h"

#include <fuchsia/hardware/ethernet/cpp/fidl.h>
#include <fuchsia/net/cpp/fidl.h>
#include <fuchsia/netstack/cpp/fidl.h>

#include <string>
#include <utility>

#include "base/format_macros.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/service_directory_client.h"
#include "base/strings/stringprintf.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_interfaces.h"

namespace net {
namespace internal {
namespace {

using ConnectionType = NetworkChangeNotifier::ConnectionType;

// Converts a Netstack NetInterface |interface| to a Chrome NetworkInterface.
// NetInterfaces may be bound to multiple IPv6 addresses. |address_index| is
// used to specify which address to use for the conversion.
//   address_index = 0: Uses NetInterface::addr, NetInterface::netmask.
//   address_index >= 1: Uses NetInterface::ipv6addrs[], with the array index
//                       offset by one.
NetworkInterface NetworkInterfaceFromAddress(
    const fuchsia::netstack::NetInterface& interface,
    size_t address_index) {
  // TODO(sergeyu): attributes field is used to return address state for IPv6
  // addresses. Currently Netstack doesn't provide this information.
  const int attributes = 0;

  IPAddress address;
  uint8_t prefix_length;
  if (address_index == 0) {
    address = FuchsiaIpAddressToIPAddress(interface.addr);
    prefix_length =
        MaskPrefixLength(FuchsiaIpAddressToIPAddress(interface.netmask));
  } else {
    CHECK_LE(address_index, interface.ipv6addrs.size());
    address = FuchsiaIpAddressToIPAddress(
        interface.ipv6addrs.at(address_index - 1).addr);
    prefix_length = interface.ipv6addrs.at(address_index - 1).prefix_len;
  }

  return NetworkInterface(interface.name, interface.name, interface.id,
                          ConvertConnectionType(interface), address,
                          prefix_length, attributes);
}

}  // namespace

NetworkChangeNotifier::ConnectionType ConvertConnectionType(
    const fuchsia::netstack::NetInterface& iface) {
  if (!(iface.flags & fuchsia::netstack::NetInterfaceFlagUp)) {
    return NetworkChangeNotifier::CONNECTION_NONE;
  } else if (iface.features & fuchsia::hardware::ethernet::INFO_FEATURE_WLAN) {
    return NetworkChangeNotifier::CONNECTION_WIFI;
  }
  return NetworkChangeNotifier::CONNECTION_UNKNOWN;
}

IPAddress FuchsiaIpAddressToIPAddress(const fuchsia::net::IpAddress& addr) {
  if (addr.is_ipv4()) {
    return IPAddress(addr.ipv4().addr.data(), addr.ipv4().addr.size());
  }
  if (addr.is_ipv6()) {
    return IPAddress(addr.ipv6().addr.data(), addr.ipv6().addr.size());
  }
  return IPAddress();
}

std::vector<NetworkInterface> NetInterfaceToNetworkInterfaces(
    const fuchsia::netstack::NetInterface& iface_in) {
  std::vector<NetworkInterface> output;

  // If the interface is not currently up then there are no addresses to return.
  if (internal::ConvertConnectionType(iface_in) ==
      NetworkChangeNotifier::CONNECTION_NONE) {
    return output;
  }

  output.push_back(NetworkInterfaceFromAddress(iface_in, 0));

  // Append interface entries for all additional IPv6 addresses.
  for (size_t i = 0; i < iface_in.ipv6addrs.size(); ++i) {
    output.push_back(NetworkInterfaceFromAddress(iface_in, i + 1));
  }

  return output;
}

}  // namespace internal

bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
  DCHECK(networks);

  fuchsia::netstack::NetstackSyncPtr netstack =
      base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
          ->ConnectToServiceSync<fuchsia::netstack::Netstack>();

  // TODO(kmarshall): Use NetworkChangeNotifier's cached interface list.
  std::vector<fuchsia::netstack::NetInterface> interfaces;
  zx_status_t status = netstack->GetInterfaces(&interfaces);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "fuchsia::netstack::GetInterfaces()";
    return false;
  }

  for (auto& interface : interfaces) {
    if ((internal::ConvertConnectionType(interface) ==
         NetworkChangeNotifier::CONNECTION_NONE) ||
        (interface.features &
         fuchsia::hardware::ethernet::INFO_FEATURE_LOOPBACK)) {
      continue;
    }

    auto converted = internal::NetInterfaceToNetworkInterfaces(interface);
    std::move(converted.begin(), converted.end(),
              std::back_inserter(*networks));
  }

  return true;
}

std::string GetWifiSSID() {
  NOTIMPLEMENTED();
  return std::string();
}

}  // namespace net
