// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_DNS_MDNS_CLIENT_H_
#define NET_DNS_MDNS_CLIENT_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/functional/callback.h"
#include "base/time/time.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "net/dns/record_parsed.h"

namespace net {

class DatagramServerSocket;
class NetLog;
class RecordParsed;

// Represents a one-time record lookup. A transaction takes one
// associated callback (see |MDnsClient::CreateTransaction|) and calls it
// whenever a matching record has been found, either from the cache or
// by querying the network (it may choose to query either or both based on its
// creation flags, see MDnsTransactionFlags). Network-based transactions will
// time out after a reasonable number of seconds.
class NET_EXPORT MDnsTransaction {
 public:
  static const base::TimeDelta kTransactionTimeout;

  // Used to signify what type of result the transaction has received.
  enum Result {
    // Passed whenever a record is found.
    RESULT_RECORD,
    // The transaction is done. Applies to non-single-valued transactions. Is
    // called when the transaction has finished (this is the last call to the
    // callback).
    RESULT_DONE,
    // No results have been found. Applies to single-valued transactions. Is
    // called when the transaction has finished without finding any results.
    // For transactions that use the network, this happens when a timeout
    // occurs, for transactions that are cache-only, this happens when no
    // results are in the cache.
    RESULT_NO_RESULTS,
    // Called when an NSec record is read for this transaction's
    // query. This means there cannot possibly be a record of the type
    // and name for this transaction.
    RESULT_NSEC
  };

  // Used when creating an MDnsTransaction.
  enum Flags {
    // Transaction should return only one result, and stop listening after it.
    // Note that single result transactions will signal when their timeout is
    // reached, whereas multi-result transactions will not.
    SINGLE_RESULT = 1 << 0,
    // Query the cache or the network. May both be used. One must be present.
    QUERY_CACHE = 1 << 1,
    QUERY_NETWORK = 1 << 2,
    // TODO(noamsml): Add flag for flushing cache when feature is implemented
    // Mask of all possible flags on MDnsTransaction.
    FLAG_MASK = (1 << 3) - 1,
  };

  typedef base::RepeatingCallback<void(Result, const RecordParsed*)>
      ResultCallback;

  // Destroying the transaction cancels it.
  virtual ~MDnsTransaction() = default;

  // Start the transaction. Return true on success. Cache-based transactions
  // will execute the callback synchronously.
  virtual bool Start() = 0;

  // Get the host or service name for the transaction.
  virtual const std::string& GetName() const = 0;

  // Get the type for this transaction (SRV, TXT, A, AAA, etc)
  virtual uint16_t GetType() const = 0;
};

// A listener listens for updates regarding a specific record or set of records.
// Created by the MDnsClient (see |MDnsClient::CreateListener|) and used to keep
// track of listeners.
//
// TODO(ericorth@chromium.org): Consider moving this inside MDnsClient to better
// organize the namespace and avoid confusion with
// net::HostResolver::MdnsListener.
class NET_EXPORT MDnsListener {
 public:
  // Used in the MDnsListener delegate to signify what type of change has been
  // made to a record.
  enum UpdateType {
    RECORD_ADDED,
    RECORD_CHANGED,
    RECORD_REMOVED
  };

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

    // Called when a record is added, removed or updated.
    virtual void OnRecordUpdate(UpdateType update,
                                const RecordParsed* record) = 0;

    // Called when a record is marked nonexistent by an NSEC record.
    virtual void OnNsecRecord(const std::string& name, unsigned type) = 0;

    // Called when the cache is purged (due, for example, ot the network
    // disconnecting).
    virtual void OnCachePurged() = 0;
  };

  // Destroying the listener stops listening.
  virtual ~MDnsListener() = default;

  // Start the listener. Return true on success.
  virtual bool Start() = 0;

  // Actively refresh any received records.
  virtual void SetActiveRefresh(bool active_refresh) = 0;

  // Get the host or service name for this query.
  // Return an empty string for no name.
  virtual const std::string& GetName() const = 0;

  // Get the type for this query (SRV, TXT, A, AAA, etc)
  virtual uint16_t GetType() const = 0;
};

// Creates bound datagram sockets ready to use by MDnsClient.
class NET_EXPORT MDnsSocketFactory {
 public:
  virtual ~MDnsSocketFactory() = default;
  virtual void CreateSockets(
      std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) = 0;

  static std::unique_ptr<MDnsSocketFactory> CreateDefault();
};

// Listens for Multicast DNS on the local network. You can access information
// regarding multicast DNS either by creating an |MDnsListener| to be notified
// of new records, or by creating an |MDnsTransaction| to look up the value of a
// specific records. When all listeners and active transactions are destroyed,
// the client stops listening on the network and destroys the cache.
class NET_EXPORT MDnsClient {
 public:
  virtual ~MDnsClient() = default;

  // Create listener object for RRType |rrtype| and name |name|.
  virtual std::unique_ptr<MDnsListener> CreateListener(
      uint16_t rrtype,
      const std::string& name,
      MDnsListener::Delegate* delegate) = 0;

  // Create a transaction that can be used to query either the MDns cache, the
  // network, or both for records of type |rrtype| and name |name|. |flags| is
  // defined by MDnsTransactionFlags.
  virtual std::unique_ptr<MDnsTransaction> CreateTransaction(
      uint16_t rrtype,
      const std::string& name,
      int flags,
      const MDnsTransaction::ResultCallback& callback) = 0;

  virtual int StartListening(MDnsSocketFactory* factory) = 0;

  // Do not call this inside callbacks from related MDnsListener and
  // MDnsTransaction objects.
  virtual void StopListening() = 0;
  virtual bool IsListening() const = 0;

  // Create the default MDnsClient
  static std::unique_ptr<MDnsClient> CreateDefault();
};

// Gets the endpoint for the multicast group a socket should join to receive
// MDNS messages. Such sockets should also bind to the endpoint from
// GetMDnsReceiveEndPoint().
//
// This is also the endpoint messages should be sent to to send MDNS messages.
NET_EXPORT IPEndPoint GetMDnsGroupEndPoint(AddressFamily address_family);

// Gets the endpoint sockets should be bound to to receive MDNS messages. Such
// sockets should also join the multicast group from GetMDnsGroupEndPoint().
NET_EXPORT IPEndPoint GetMDnsReceiveEndPoint(AddressFamily address_family);

typedef std::vector<std::pair<uint32_t, AddressFamily>>
    InterfaceIndexFamilyList;
// Returns pairs of interface and address family to bind. Current
// implementation returns unique list of all available interfaces.
NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind();

// Create sockets, binds socket to MDns endpoint, and sets multicast interface
// and joins multicast group on for |interface_index|.
// Returns NULL if failed.
NET_EXPORT std::unique_ptr<DatagramServerSocket> CreateAndBindMDnsSocket(
    AddressFamily address_family,
    uint32_t interface_index,
    NetLog* net_log);

}  // namespace net

#endif  // NET_DNS_MDNS_CLIENT_H_
