/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef P2P_BASE_RELAYSERVER_H_
#define P2P_BASE_RELAYSERVER_H_

#include <map>
#include <string>
#include <vector>

#include "p2p/base/port.h"
#include "p2p/base/stun.h"
#include "rtc_base/asyncudpsocket.h"
#include "rtc_base/random.h"
#include "rtc_base/socketaddresspair.h"
#include "rtc_base/thread.h"
#include "rtc_base/timeutils.h"

namespace cricket {

class RelayServerBinding;
class RelayServerConnection;

// Relays traffic between connections to the server that are "bound" together.
// All connections created with the same username/password are bound together.
class RelayServer : public rtc::MessageHandler, public sigslot::has_slots<> {
 public:
  // Creates a server, which will use this thread to post messages to itself.
  explicit RelayServer(rtc::Thread* thread);
  ~RelayServer() override;

  rtc::Thread* thread() { return thread_; }

  // Indicates whether we will print updates of the number of bindings.
  bool log_bindings() const { return log_bindings_; }
  void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }

  // Updates the set of sockets that the server uses to talk to "internal"
  // clients.  These are clients that do the "port allocations".
  void AddInternalSocket(rtc::AsyncPacketSocket* socket);
  void RemoveInternalSocket(rtc::AsyncPacketSocket* socket);

  // Updates the set of sockets that the server uses to talk to "external"
  // clients.  These are the clients that do not do allocations.  They do not
  // know that these addresses represent a relay server.
  void AddExternalSocket(rtc::AsyncPacketSocket* socket);
  void RemoveExternalSocket(rtc::AsyncPacketSocket* socket);

  // Starts listening for connections on this sockets. When someone
  // tries to connect, the connection will be accepted and a new
  // internal socket will be added.
  void AddInternalServerSocket(rtc::AsyncSocket* socket,
                               cricket::ProtocolType proto);

  // Removes this server socket from the list.
  void RemoveInternalServerSocket(rtc::AsyncSocket* socket);

  // Methods for testing and debuging.
  int GetConnectionCount() const;
  rtc::SocketAddressPair GetConnection(int connection) const;
  bool HasConnection(const rtc::SocketAddress& address) const;

 private:
  typedef std::vector<rtc::AsyncPacketSocket*> SocketList;
  typedef std::map<rtc::AsyncSocket*, cricket::ProtocolType> ServerSocketMap;
  typedef std::map<std::string, RelayServerBinding*> BindingMap;
  typedef std::map<rtc::SocketAddressPair, RelayServerConnection*>
      ConnectionMap;

  rtc::Thread* thread_;
  webrtc::Random random_;
  bool log_bindings_;
  SocketList internal_sockets_;
  SocketList external_sockets_;
  SocketList removed_sockets_;
  ServerSocketMap server_sockets_;
  BindingMap bindings_;
  ConnectionMap connections_;

  // Called when a packet is received by the server on one of its sockets.
  void OnInternalPacket(rtc::AsyncPacketSocket* socket,
                        const char* bytes,
                        size_t size,
                        const rtc::SocketAddress& remote_addr,
                        const rtc::PacketTime& packet_time);
  void OnExternalPacket(rtc::AsyncPacketSocket* socket,
                        const char* bytes,
                        size_t size,
                        const rtc::SocketAddress& remote_addr,
                        const rtc::PacketTime& packet_time);

  void OnReadEvent(rtc::AsyncSocket* socket);

  // Processes the relevant STUN request types from the client.
  bool HandleStun(const char* bytes,
                  size_t size,
                  const rtc::SocketAddress& remote_addr,
                  rtc::AsyncPacketSocket* socket,
                  std::string* username,
                  StunMessage* msg);
  void HandleStunAllocate(const char* bytes,
                          size_t size,
                          const rtc::SocketAddressPair& ap,
                          rtc::AsyncPacketSocket* socket);
  void HandleStun(RelayServerConnection* int_conn,
                  const char* bytes,
                  size_t size);
  void HandleStunAllocate(RelayServerConnection* int_conn,
                          const StunMessage& msg);
  void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);

  // Adds/Removes the a connection or binding.
  void AddConnection(RelayServerConnection* conn);
  void RemoveConnection(RelayServerConnection* conn);
  void RemoveBinding(RelayServerBinding* binding);

  // Handle messages in our thread.
  void OnMessage(rtc::Message* pmsg) override;

  // Called when the timer for checking lifetime times out.
  void OnTimeout(RelayServerBinding* binding);

  // Accept connections on this server socket.
  void AcceptConnection(rtc::AsyncSocket* server_socket);

  friend class RelayServerConnection;
  friend class RelayServerBinding;
};

// Maintains information about a connection to the server.  Each connection is
// part of one and only one binding.
class RelayServerConnection {
 public:
  RelayServerConnection(RelayServerBinding* binding,
                        const rtc::SocketAddressPair& addrs,
                        rtc::AsyncPacketSocket* socket);
  ~RelayServerConnection();

  RelayServerBinding* binding() { return binding_; }
  rtc::AsyncPacketSocket* socket() { return socket_; }

  // Returns a pair where the source is the remote address and the destination
  // is the local address.
  const rtc::SocketAddressPair& addr_pair() { return addr_pair_; }

  // Sends a packet to the connected client.  If an address is provided, then
  // we make sure the internal client receives it, wrapping if necessary.
  void Send(const char* data, size_t size);
  void Send(const char* data, size_t size, const rtc::SocketAddress& ext_addr);

  // Sends a STUN message to the connected client with no wrapping.
  void SendStun(const StunMessage& msg);
  void SendStunError(const StunMessage& request, int code, const char* desc);

  // A locked connection is one for which we know the intended destination of
  // any raw packet received.
  bool locked() const { return locked_; }
  void Lock();
  void Unlock();

  // Records the address that raw packets should be forwarded to (for internal
  // packets only; for external, we already know where they go).
  const rtc::SocketAddress& default_destination() const {
    return default_dest_;
  }
  void set_default_destination(const rtc::SocketAddress& addr) {
    default_dest_ = addr;
  }

 private:
  RelayServerBinding* binding_;
  rtc::SocketAddressPair addr_pair_;
  rtc::AsyncPacketSocket* socket_;
  bool locked_;
  rtc::SocketAddress default_dest_;
};

// Records a set of internal and external connections that we relay between,
// or in other words, that are "bound" together.
class RelayServerBinding : public rtc::MessageHandler {
 public:
  RelayServerBinding(RelayServer* server,
                     const std::string& username,
                     const std::string& password,
                     int lifetime);
  ~RelayServerBinding() override;

  RelayServer* server() { return server_; }
  int lifetime() { return lifetime_; }
  const std::string& username() { return username_; }
  const std::string& password() { return password_; }
  const std::string& magic_cookie() { return magic_cookie_; }

  // Adds/Removes a connection into the binding.
  void AddInternalConnection(RelayServerConnection* conn);
  void AddExternalConnection(RelayServerConnection* conn);

  // We keep track of the use of each binding.  If we detect that it was not
  // used for longer than the lifetime, then we send a signal.
  void NoteUsed();
  sigslot::signal1<RelayServerBinding*> SignalTimeout;

  // Determines whether the given packet has the magic cookie present (in the
  // right place).
  bool HasMagicCookie(const char* bytes, size_t size) const;

  // Determines the connection to use to send packets to or from the given
  // external address.
  RelayServerConnection* GetInternalConnection(
      const rtc::SocketAddress& ext_addr);
  RelayServerConnection* GetExternalConnection(
      const rtc::SocketAddress& ext_addr);

  // MessageHandler:
  void OnMessage(rtc::Message* pmsg) override;

 private:
  RelayServer* server_;

  std::string username_;
  std::string password_;
  std::string magic_cookie_;

  std::vector<RelayServerConnection*> internal_connections_;
  std::vector<RelayServerConnection*> external_connections_;

  int lifetime_;
  int64_t last_used_;
  // TODO(?): bandwidth
};

}  // namespace cricket

#endif  // P2P_BASE_RELAYSERVER_H_
