// 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 "osp/impl/internal_services.h"

#include <algorithm>
#include <utility>

#include "osp/impl/discovery/mdns/mdns_responder_adapter_impl.h"
#include "osp/impl/mdns_responder_service.h"
#include "platform/api/udp_socket.h"
#include "platform/base/error.h"
#include "util/osp_logging.h"

namespace openscreen {
namespace osp {
namespace {

constexpr char kServiceName[] = "_openscreen";
constexpr char kServiceProtocol[] = "_udp";
const IPAddress kMulticastAddress{224, 0, 0, 251};
const IPAddress kMulticastIPv6Address{
    // ff02::fb
    0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fb,
};
const uint16_t kMulticastListeningPort = 5353;

class MdnsResponderAdapterImplFactory final
    : public MdnsResponderAdapterFactory {
 public:
  MdnsResponderAdapterImplFactory() = default;
  ~MdnsResponderAdapterImplFactory() override = default;

  std::unique_ptr<MdnsResponderAdapter> Create() override {
    return std::make_unique<MdnsResponderAdapterImpl>();
  }
};

Error SetUpMulticastSocket(UdpSocket* socket, NetworkInterfaceIndex ifindex) {
  const IPAddress broadcast_address =
      socket->IsIPv6() ? kMulticastIPv6Address : kMulticastAddress;

  socket->JoinMulticastGroup(broadcast_address, ifindex);
  socket->SetMulticastOutboundInterface(ifindex);
  socket->Bind();

  return Error::None();
}

// Ref-counted singleton instance of InternalServices. This lives only as long
// as there is at least one ServiceListener and/or ServicePublisher alive.
InternalServices* g_instance = nullptr;
int g_instance_ref_count = 0;

}  // namespace

// static
std::unique_ptr<ServiceListener> InternalServices::CreateListener(
    const MdnsServiceListenerConfig& config,
    ServiceListener::Observer* observer,
    TaskRunner* task_runner) {
  auto* services = ReferenceSingleton(task_runner);
  auto listener =
      std::make_unique<ServiceListenerImpl>(&services->mdns_service_);
  listener->AddObserver(observer);
  listener->SetDestructionCallback(&InternalServices::DereferenceSingleton,
                                   services);
  return listener;
}

// static
std::unique_ptr<ServicePublisher> InternalServices::CreatePublisher(
    const ServicePublisher::Config& config,
    ServicePublisher::Observer* observer,
    TaskRunner* task_runner) {
  auto* services = ReferenceSingleton(task_runner);
  services->mdns_service_.SetServiceConfig(
      config.hostname, config.service_instance_name,
      config.connection_server_port, config.network_interface_indices,
      {{"fn", config.friendly_name}});
  auto publisher = std::make_unique<ServicePublisherImpl>(
      observer, &services->mdns_service_);
  publisher->SetDestructionCallback(&InternalServices::DereferenceSingleton,
                                    services);
  return publisher;
}

InternalServices::InternalPlatformLinkage::InternalPlatformLinkage(
    InternalServices* parent)
    : parent_(parent) {}

InternalServices::InternalPlatformLinkage::~InternalPlatformLinkage() {
  // If there are open sockets, then there will be dangling references to
  // destroyed objects after destruction.
  OSP_CHECK(open_sockets_.empty());
}

std::vector<MdnsPlatformService::BoundInterface>
InternalServices::InternalPlatformLinkage::RegisterInterfaces(
    const std::vector<NetworkInterfaceIndex>& allowlist) {
  const std::vector<InterfaceInfo> interfaces = GetNetworkInterfaces();
  const bool do_filter_using_allowlist = !allowlist.empty();
  std::vector<NetworkInterfaceIndex> index_list;
  for (const auto& interface : interfaces) {
    OSP_VLOG << "Found interface: " << interface;
    if (do_filter_using_allowlist &&
        std::find(allowlist.begin(), allowlist.end(), interface.index) ==
            allowlist.end()) {
      OSP_VLOG << "Ignoring interface not in allowed list: " << interface;
      continue;
    }
    if (!interface.addresses.empty())
      index_list.push_back(interface.index);
  }
  OSP_LOG_IF(WARN, index_list.empty())
      << "No network interfaces had usable addresses for mDNS.";

  // Set up sockets to send and listen to mDNS multicast traffic on all
  // interfaces.
  std::vector<BoundInterface> result;
  for (NetworkInterfaceIndex index : index_list) {
    const auto& interface = *std::find_if(
        interfaces.begin(), interfaces.end(),
        [index](const InterfaceInfo& info) { return info.index == index; });
    if (interface.addresses.empty()) {
      continue;
    }

    // Pick any address for the given interface.
    const IPSubnet& primary_subnet = interface.addresses.front();

    auto create_result =
        UdpSocket::Create(parent_->task_runner_, parent_,
                          IPEndpoint{{}, kMulticastListeningPort});
    if (!create_result) {
      OSP_LOG_ERROR << "failed to create socket for interface " << index << ": "
                    << create_result.error().message();
      continue;
    }
    std::unique_ptr<UdpSocket> socket = std::move(create_result.value());
    if (!SetUpMulticastSocket(socket.get(), index).ok()) {
      continue;
    }
    result.emplace_back(interface, primary_subnet, socket.get());
    parent_->RegisterMdnsSocket(socket.get());

    open_sockets_.emplace_back(std::move(socket));
  }

  return result;
}

void InternalServices::InternalPlatformLinkage::DeregisterInterfaces(
    const std::vector<BoundInterface>& registered_interfaces) {
  for (const auto& interface : registered_interfaces) {
    UdpSocket* const socket = interface.socket;
    parent_->DeregisterMdnsSocket(socket);

    const auto it = std::find_if(open_sockets_.begin(), open_sockets_.end(),
                                 [socket](const std::unique_ptr<UdpSocket>& s) {
                                   return s.get() == socket;
                                 });
    OSP_DCHECK(it != open_sockets_.end());
    open_sockets_.erase(it);
  }
}

InternalServices::InternalServices(ClockNowFunctionPtr now_function,
                                   TaskRunner* task_runner)
    : mdns_service_(now_function,
                    task_runner,
                    kServiceName,
                    kServiceProtocol,
                    std::make_unique<MdnsResponderAdapterImplFactory>(),
                    std::make_unique<InternalPlatformLinkage>(this)),
      task_runner_(task_runner) {}

InternalServices::~InternalServices() = default;

void InternalServices::RegisterMdnsSocket(UdpSocket* socket) {
  OSP_CHECK(g_instance) << "No listener or publisher is alive.";
  // TODO(rwkeane): Hook this up to the new mDNS library once we swap out the
  // mDNSResponder.
}

void InternalServices::DeregisterMdnsSocket(UdpSocket* socket) {
  // TODO(rwkeane): Hook this up to the new mDNS library once we swap out the
  // mDNSResponder.
}

// static
InternalServices* InternalServices::ReferenceSingleton(
    TaskRunner* task_runner) {
  if (!g_instance) {
    OSP_CHECK_EQ(g_instance_ref_count, 0);
    g_instance = new InternalServices(&Clock::now, task_runner);
  }
  ++g_instance_ref_count;
  return g_instance;
}

// static
void InternalServices::DereferenceSingleton(void* instance) {
  OSP_CHECK_EQ(static_cast<InternalServices*>(instance), g_instance);
  OSP_CHECK_GT(g_instance_ref_count, 0);
  --g_instance_ref_count;
  if (g_instance_ref_count == 0) {
    delete g_instance;
    g_instance = nullptr;
  }
}

void InternalServices::OnError(UdpSocket* socket, Error error) {
  OSP_LOG_ERROR << "failed to configure socket " << error.message();
  this->DeregisterMdnsSocket(socket);
}

void InternalServices::OnSendError(UdpSocket* socket, Error error) {
  // TODO(crbug.com/openscreen/67): Implement this method.
  OSP_UNIMPLEMENTED();
}

void InternalServices::OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) {
  g_instance->mdns_service_.OnRead(socket, std::move(packet));
}

}  // namespace osp
}  // namespace openscreen
