// Copyright 2017 The Fuchsia 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 "garnet/bin/netconnector/host_name.h"

#include <fuchsia/netstack/cpp/fidl.h>
#include <limits.h>
#include <unistd.h>

#include "garnet/lib/inet/socket_address.h"
#include "lib/component/cpp/startup_context.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/logging.h"

namespace netconnector {
namespace {

static const std::string kFuchsia = "fuchsia-unset-device-name";

class NetstackClient {
 public:
  static void GetInterfaces(
      fuchsia::netstack::Netstack::GetInterfacesCallback callback) {
    NetstackClient* client = new NetstackClient();
    client->netstack_->GetInterfaces(
        [client, callback = std::move(callback)](
            std::vector<fuchsia::netstack::NetInterface> interfaces) {
          callback(std::move(interfaces));
          delete client;
        });
  }

 private:
  NetstackClient()
      : context_(component::StartupContext::CreateFromStartupInfo()) {
    FXL_DCHECK(context_);
    netstack_ =
        context_->ConnectToEnvironmentService<fuchsia::netstack::Netstack>();
    FXL_DCHECK(netstack_);
  }

  std::unique_ptr<component::StartupContext> context_;
  fuchsia::netstack::NetstackPtr netstack_;
};

// Returns a host address, preferably V4. Returns an invalid address if no
// network interface could be found or if the interface hasn't obtained an
// address.
inet::IpAddress GetHostAddress() {
  static inet::IpAddress ip_address;
  if (ip_address)
    return ip_address;

  NetstackClient::GetInterfaces(
      [](const std::vector<fuchsia::netstack::NetInterface>& interfaces) {
        for (const auto& interface : interfaces) {
          if (interface.addr.Which() == fuchsia::net::IpAddress::Tag::kIpv4) {
            ip_address = inet::IpAddress(&interface.addr);
            break;
          }
          if (interface.addr.Which() == fuchsia::net::IpAddress::Tag::kIpv6) {
            ip_address = inet::IpAddress(&interface.addr);
            // Keep looking...v4 is preferred.
          }
        }
      });

  return inet::IpAddress::kInvalid;
}

}  // namespace

bool NetworkIsReady() { return GetHostAddress().is_valid(); }

// TODO: this should probably be an asynchronous interface.
std::string GetHostName() {
  char host_name_buffer[HOST_NAME_MAX + 1];
  int result = gethostname(host_name_buffer, sizeof(host_name_buffer));

  std::string host_name;

  if (result < 0) {
    FXL_LOG(ERROR) << "gethostname failed, errno " << errno;
    host_name = kFuchsia;
  } else {
    host_name = host_name_buffer;
  }

  // TODO(dalesat): Just use gethostname when NET-79 is fixed.

  if (host_name == kFuchsia) {
    // Seems we have the hard-coded host name. Supplement it with part of the
    // IP address.
    inet::IpAddress address = GetHostAddress();
    if (address) {
      uint16_t suffix = address.is_v4()
                            ? static_cast<uint16_t>(
                                  address.as_bytes()[address.byte_count() - 1])
                            : address.as_words()[address.word_count() - 1];
      std::ostringstream os;
      os << host_name << "-" << suffix;
      host_name = os.str();
    }
  }

  return host_name;
}

}  // namespace netconnector
