// 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.

#ifndef OSP_IMPL_MDNS_RESPONDER_SERVICE_H_
#define OSP_IMPL_MDNS_RESPONDER_SERVICE_H_

#include <array>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "osp/impl/discovery/mdns/mdns_responder_adapter.h"
#include "osp/impl/mdns_platform_service.h"
#include "osp/impl/service_listener_impl.h"
#include "osp/impl/service_publisher_impl.h"
#include "platform/api/network_interface.h"
#include "platform/api/task_runner.h"
#include "platform/api/time.h"
#include "platform/base/ip_address.h"
#include "util/alarm.h"

namespace openscreen {
namespace osp {

class MdnsResponderAdapterFactory {
 public:
  virtual ~MdnsResponderAdapterFactory() = default;

  virtual std::unique_ptr<MdnsResponderAdapter> Create() = 0;
};

class MdnsResponderService : public ServiceListenerImpl::Delegate,
                             public ServicePublisherImpl::Delegate,
                             public UdpSocket::Client {
 public:
  MdnsResponderService(
      ClockNowFunctionPtr now_function,
      TaskRunner* task_runner,
      const std::string& service_name,
      const std::string& service_protocol,
      std::unique_ptr<MdnsResponderAdapterFactory> mdns_responder_factory,
      std::unique_ptr<MdnsPlatformService> platform);
  ~MdnsResponderService() override;

  void SetServiceConfig(const std::string& hostname,
                        const std::string& instance,
                        uint16_t port,
                        const std::vector<NetworkInterfaceIndex> allowlist,
                        const std::map<std::string, std::string>& txt_data);

  // UdpSocket::Client overrides.
  void OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) override;
  void OnSendError(UdpSocket* socket, Error error) override;
  void OnError(UdpSocket* socket, Error error) override;

  // ServiceListenerImpl::Delegate overrides.
  void StartListener() override;
  void StartAndSuspendListener() override;
  void StopListener() override;
  void SuspendListener() override;
  void ResumeListener() override;
  void SearchNow(ServiceListener::State from) override;

  // ServicePublisherImpl::Delegate overrides.
  void StartPublisher() override;
  void StartAndSuspendPublisher() override;
  void StopPublisher() override;
  void SuspendPublisher() override;
  void ResumePublisher() override;

 protected:
  void HandleMdnsEvents();

  std::unique_ptr<MdnsResponderAdapter> mdns_responder_;

 private:
  // Create internal versions of all public methods. These are used to push all
  // calls to these methods to the task runner.
  // TODO(rwkeane): Clean up these methods. Some result in multiple pushes to
  // the task runner when just one would suffice.
  // ServiceListenerImpl::Delegate overrides.
  void StartListenerInternal();
  void StartAndSuspendListenerInternal();
  void StopListenerInternal();
  void SuspendListenerInternal();
  void ResumeListenerInternal();
  void SearchNowInternal(ServiceListener::State from);
  void StartPublisherInternal();
  void StartAndSuspendPublisherInternal();
  void StopPublisherInternal();
  void SuspendPublisherInternal();
  void ResumePublisherInternal();

  // NOTE: service_instance implicit in map key.
  struct ServiceInstance {
    UdpSocket* ptr_socket = nullptr;
    DomainName domain_name;
    uint16_t port = 0;
    bool has_ptr_record = false;
    std::vector<std::string> txt_info;

    // |port| == 0 signals that we have no SRV record.
    bool has_srv() const { return port != 0; }
  };

  // NOTE: hostname implicit in map key.
  struct HostInfo {
    std::vector<ServiceInstance*> services;
    IPAddress v4_address;
    IPAddress v6_address;
  };

  struct NetworkScopedDomainName {
    UdpSocket* socket;
    DomainName domain_name;
  };

  struct NetworkScopedDomainNameComparator {
    bool operator()(const NetworkScopedDomainName& a,
                    const NetworkScopedDomainName& b) const;
  };

  using InstanceNameSet = std::set<DomainName, DomainNameComparator>;

  void StartListening();
  void StopListening();
  void StartService();
  void StopService();
  void StopMdnsResponder();
  void UpdatePendingServiceInfoSet(InstanceNameSet* modified_instance_names,
                                   const DomainName& domain_name);
  void RemoveAllReceivers();

  // NOTE: |modified_instance_names| is used to track which service instances
  // are modified by the record events.  See HandleMdnsEvents for more details.
  bool HandlePtrEvent(const PtrEvent& ptr_event,
                      InstanceNameSet* modified_instance_names);
  bool HandleSrvEvent(const SrvEvent& srv_event,
                      InstanceNameSet* modified_instance_names);
  bool HandleTxtEvent(const TxtEvent& txt_event,
                      InstanceNameSet* modified_instance_names);
  bool HandleAddressEvent(UdpSocket* socket,
                          QueryEventHeader::Type response_type,
                          const DomainName& domain_name,
                          bool a_event,
                          const IPAddress& address,
                          InstanceNameSet* modified_instance_names);
  bool HandleAEvent(const AEvent& a_event,
                    InstanceNameSet* modified_instance_names);
  bool HandleAaaaEvent(const AaaaEvent& aaaa_event,
                       InstanceNameSet* modified_instance_names);

  HostInfo* AddOrGetHostInfo(UdpSocket* socket, const DomainName& domain_name);
  HostInfo* GetHostInfo(UdpSocket* socket, const DomainName& domain_name);
  bool IsServiceReady(const ServiceInstance& instance, HostInfo* host) const;
  NetworkInterfaceIndex GetNetworkInterfaceIndexFromSocket(
      const UdpSocket* socket) const;

  // Runs background tasks to manage the internal mDNS state.
  void RunBackgroundTasks();

  // Service type separated as service name and service protocol for both
  // listening and publishing (e.g. {"_openscreen", "_udp"}).
  std::array<std::string, 2> service_type_;

  // The following variables all relate to what MdnsResponderService publishes,
  // if anything.
  std::string service_hostname_;
  std::string service_instance_name_;
  uint16_t service_port_;
  std::vector<NetworkInterfaceIndex> interface_index_allowlist_;
  std::map<std::string, std::string> service_txt_data_;

  std::unique_ptr<MdnsResponderAdapterFactory> mdns_responder_factory_;
  std::unique_ptr<MdnsPlatformService> platform_;
  std::vector<MdnsPlatformService::BoundInterface> bound_interfaces_;

  // A map of service information collected from PTR, SRV, and TXT records.  It
  // is keyed by service instance names.
  std::map<DomainName, std::unique_ptr<ServiceInstance>, DomainNameComparator>
      service_by_name_;

  // The map key is a combination of the interface to which the address records
  // belong and the hostname of the address records.  The values are IPAddresses
  // for the given hostname on the given network and pointers to dependent
  // service instances.  The service instance pointers act as a reference count
  // to keep the A/AAAA queries alive, when more than one service refers to the
  // same hostname.  This is not currently used by openscreen, but is used by
  // Cast, so may be supported in openscreen in the future.
  std::map<NetworkScopedDomainName, HostInfo, NetworkScopedDomainNameComparator>
      network_scoped_domain_to_host_;

  std::map<std::string, ServiceInfo> receiver_info_;

  TaskRunner* const task_runner_;

  // Scheduled to run periodic background tasks.
  Alarm background_tasks_alarm_;

  friend class TestingMdnsResponderService;
};

}  // namespace osp
}  // namespace openscreen

#endif  // OSP_IMPL_MDNS_RESPONDER_SERVICE_H_
