// Copyright 2018 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_change_notifier_fuchsia.h"

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "base/fuchsia/component_context.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "net/base/network_interfaces.h"
#include "net/base/network_interfaces_fuchsia.h"

namespace net {
namespace {

using ConnectionType = NetworkChangeNotifier::ConnectionType;

// Adapts a base::RepeatingCallback to a std::function object.
// Useful when binding callbacks to asynchronous FIDL calls, because
// it allows the caller to reference in-scope move-only objects as well as use
// Chromium's ownership signifiers such as base::Passed, base::Unretained, etc.
//
// Note that the function takes a RepeatingCallback because it is copyable, but
// in practice the callback will only be executed once by the FIDL system.
template <typename R, typename... Args>
std::function<R(Args...)> WrapCallbackAsFunction(
    base::RepeatingCallback<R(Args...)> callback) {
  return
      [callback](Args... args) { callback.Run(std::forward<Args>(args)...); };
}

}  // namespace

NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia()
    : NetworkChangeNotifierFuchsia(
          base::fuchsia::ComponentContext::GetDefault()
              ->ConnectToService<fuchsia::netstack::Netstack>()) {}

NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia(
    fuchsia::netstack::NetstackPtr netstack)
    : listener_binding_(this), netstack_(std::move(netstack)) {
  DCHECK(netstack_);

  listener_binding_.set_error_handler([this]() {
    LOG(ERROR) << "Lost connection to netstack.";
    listener_binding_.set_error_handler(nullptr);
    listener_binding_.Unbind();
  });
  netstack_->RegisterListener(listener_binding_.NewBinding());

  // Wait until we get the interface list before proceeding, to prevent racy
  // accesses of GetCurrentConnectionType().
  base::RunLoop initialized_runloop;
  netstack_->GetInterfaces([
    this, quit_closure = initialized_runloop.QuitClosure()
  ](fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces) {
    ProcessInterfaceList(quit_closure, std::move(interfaces));
  });
  initialized_runloop.Run();
}

NetworkChangeNotifierFuchsia::~NetworkChangeNotifierFuchsia() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}

NetworkChangeNotifier::ConnectionType
NetworkChangeNotifierFuchsia::GetCurrentConnectionType() const {
  ConnectionType type = static_cast<ConnectionType>(
      base::subtle::Acquire_Load(&cached_connection_type_));
  return type;
}

void NetworkChangeNotifierFuchsia::OnInterfacesChanged(
    fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces) {
  ProcessInterfaceList(base::OnceClosure(), std::move(interfaces));
}

void NetworkChangeNotifierFuchsia::ProcessInterfaceList(
    base::OnceClosure on_initialized_cb,
    fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces) {
  netstack_->GetRouteTable(WrapCallbackAsFunction(base::BindRepeating(
      &NetworkChangeNotifierFuchsia::OnRouteTableReceived,
      base::Unretained(this), base::Passed(std::move(on_initialized_cb)),
      base::Passed(std::move(interfaces)))));
}

void NetworkChangeNotifierFuchsia::OnRouteTableReceived(
    base::OnceClosure on_initialized_cb,
    fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces,
    fidl::VectorPtr<fuchsia::netstack::RouteTableEntry> route_table) {
  // Find the default interface in the routing table.
  auto default_route_interface = std::find_if(
      route_table->begin(), route_table->end(),
      [](const fuchsia::netstack::RouteTableEntry& rt) {
        return MaskPrefixLength(internal::NetAddressToIPAddress(rt.netmask)) ==
               0;
      });

  // Find the default interface in the NetInterface list.
  const fuchsia::netstack::NetInterface* default_interface = nullptr;
  if (default_route_interface != route_table->end()) {
    for (const auto& cur_interface : *interfaces) {
      if (cur_interface.id == default_route_interface->nicid) {
        default_interface = &cur_interface;
      }
    }
  }

  base::flat_set<IPAddress> addresses;
  std::string ssid;
  ConnectionType connection_type = CONNECTION_NONE;
  if (default_interface) {
    std::vector<NetworkInterface> flattened_interfaces =
        internal::NetInterfaceToNetworkInterfaces(*default_interface);
    std::transform(
        flattened_interfaces.begin(), flattened_interfaces.end(),
        std::inserter(addresses, addresses.begin()),
        [](const NetworkInterface& interface) { return interface.address; });
    if (!flattened_interfaces.empty()) {
      connection_type = flattened_interfaces.front().type;
    }

    // TODO(https://crbug.com/848355): Treat SSID changes as IP address changes.
  }

  bool connection_type_changed = false;
  if (connection_type != cached_connection_type_) {
    base::subtle::Release_Store(&cached_connection_type_, connection_type);
    connection_type_changed = true;
  }

  if (addresses != cached_addresses_) {
    std::swap(cached_addresses_, addresses);
    if (on_initialized_cb.is_null()) {
      NotifyObserversOfIPAddressChange();
    }
    connection_type_changed = true;
  }

  if (on_initialized_cb.is_null() && connection_type_changed) {
    NotifyObserversOfConnectionTypeChange();
  }

  if (!on_initialized_cb.is_null()) {
    std::move(on_initialized_cb).Run();
  }
}

}  // namespace net
