/*
 *  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 WEBRTC_RTC_BASE_HTTPSERVER_H_
#define WEBRTC_RTC_BASE_HTTPSERVER_H_

#include <map>
#include <memory>

#include "webrtc/rtc_base/httpbase.h"

namespace rtc {

class AsyncSocket;
class HttpServer;
class SocketAddress;

//////////////////////////////////////////////////////////////////////
// HttpServer
//////////////////////////////////////////////////////////////////////

const int HTTP_INVALID_CONNECTION_ID = 0;

struct HttpServerTransaction : public HttpTransaction {
public:
  HttpServerTransaction(int id) : connection_id_(id) { }
  int connection_id() const { return connection_id_; }

private:
  int connection_id_;
};

class HttpServer {
public:
  HttpServer();
  virtual ~HttpServer();

  int HandleConnection(StreamInterface* stream);
  // Due to sigslot issues, we can't destroy some streams at an arbitrary time.
  sigslot::signal3<HttpServer*, int, StreamInterface*> SignalConnectionClosed;

  // This signal occurs when the HTTP request headers have been received, but
  // before the request body is written to the request document.  By default,
  // the request document is a MemoryStream.  By handling this signal, the
  // document can be overridden, in which case the third signal argument should
  // be set to true.  In the case where the request body should be ignored,
  // the document can be set to null.  Note that the transaction object is still
  // owened by the HttpServer at this point.
  sigslot::signal3<HttpServer*, HttpServerTransaction*, bool*>
    SignalHttpRequestHeader;

  // An HTTP request has been made, and is available in the transaction object.
  // Populate the transaction's response, and then return the object via the
  // Respond method.  Note that during this time, ownership of the transaction
  // object is transferred, so it may be passed between threads, although
  // respond must be called on the server's active thread.
  sigslot::signal2<HttpServer*, HttpServerTransaction*> SignalHttpRequest;
  void Respond(HttpServerTransaction* transaction);

  // If you want to know when a request completes, listen to this event.
  sigslot::signal3<HttpServer*, HttpServerTransaction*, int>
    SignalHttpRequestComplete;

  // Stop processing the connection indicated by connection_id.
  // Unless force is true, the server will complete sending a response that is
  // in progress.
  void Close(int connection_id, bool force);
  void CloseAll(bool force);

  // After calling CloseAll, this event is signalled to indicate that all
  // outstanding connections have closed.
  sigslot::signal1<HttpServer*> SignalCloseAllComplete;

private:
  class Connection : private IHttpNotify {
  public:
    Connection(int connection_id, HttpServer* server);
    ~Connection() override;

    void BeginProcess(StreamInterface* stream);
    StreamInterface* EndProcess();

    void Respond(HttpServerTransaction* transaction);
    void InitiateClose(bool force);

    // IHttpNotify Interface
    HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) override;
    void onHttpComplete(HttpMode mode, HttpError err) override;
    void onHttpClosed(HttpError err) override;

    int connection_id_;
    HttpServer* server_;
    HttpBase base_;
    HttpServerTransaction* current_;
    bool signalling_, close_;
  };

  Connection* Find(int connection_id);
  void Remove(int connection_id);

  friend class Connection;
  typedef std::map<int,Connection*> ConnectionMap;

  ConnectionMap connections_;
  int next_connection_id_;
  bool closing_;
};

//////////////////////////////////////////////////////////////////////

class HttpListenServer : public HttpServer, public sigslot::has_slots<> {
public:
  HttpListenServer();
  ~HttpListenServer() override;

  int Listen(const SocketAddress& address);
  bool GetAddress(SocketAddress* address) const;
  void StopListening();

private:
  void OnReadEvent(AsyncSocket* socket);
  void OnConnectionClosed(HttpServer* server, int connection_id,
                          StreamInterface* stream);

  std::unique_ptr<AsyncSocket> listener_;
};

//////////////////////////////////////////////////////////////////////

}  // namespace rtc

#endif // WEBRTC_RTC_BASE_HTTPSERVER_H_
