// 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.count());
  }
  if (addr.is_ipv6()) {
    return IPAddress(addr.ipv6().addr.data(), addr.ipv6().addr.count());
  }
  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
