/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "tscore/ink_config.h"
#include "P_Net.h"
#include "HttpConfig.h"
#include "HttpSessionAccept.h"
#include "ReverseProxy.h"
#include "HttpSessionManager.h"
#ifdef USE_HTTP_DEBUG_LISTS
#include "Http1ClientSession.h"
#endif
#include "HttpPages.h"
#include "HttpTunnel.h"
#include "tscore/Tokenizer.h"
#include "P_SSLNextProtocolAccept.h"
#include "ProtocolProbeSessionAccept.h"
#include "http2/Http2SessionAccept.h"
#include "HttpConnectionCount.h"
#include "HttpProxyServerMain.h"
#if TS_USE_QUIC == 1
#include "P_QUICNetProcessor.h"
#include "P_QUICNextProtocolAccept.h"
#include "http3/Http3SessionAccept.h"
#endif

#include <vector>

HttpSessionAccept *plugin_http_accept             = nullptr;
HttpSessionAccept *plugin_http_transparent_accept = nullptr;

static SLL<SSLNextProtocolAccept> ssl_plugin_acceptors;
static Ptr<ProxyMutex> ssl_plugin_mutex;

std::mutex proxyServerMutex;
std::condition_variable proxyServerCheck;
bool et_net_threads_ready = false;

std::mutex etUdpMutex;
std::condition_variable etUdpCheck;
bool et_udp_threads_ready = false;

extern int num_of_net_threads;
extern int num_accept_threads;

/// Global BufferWriter format name functions.
namespace
{
void
TS_bwf_thread(ts::BufferWriter &w, ts::BWFSpec const &spec)
{
  bwformat(w, spec, this_thread());
}
void
TS_bwf_ethread(ts::BufferWriter &w, ts::BWFSpec const &spec)
{
  bwformat(w, spec, this_ethread());
}
} // namespace

// File / process scope initializations
static bool HTTP_SERVER_INITIALIZED __attribute__((unused)) = []() -> bool {
  ts::bwf_register_global("ts-thread", &TS_bwf_thread);
  ts::bwf_register_global("ts-ethread", &TS_bwf_ethread);
  return true;
}();

bool
ssl_register_protocol(const char *protocol, Continuation *contp)
{
  SCOPED_MUTEX_LOCK(lock, ssl_plugin_mutex, this_ethread());

  for (SSLNextProtocolAccept *ssl = ssl_plugin_acceptors.head; ssl; ssl = ssl_plugin_acceptors.next(ssl)) {
    if (!ssl->registerEndpoint(protocol, contp)) {
      return false;
    }
  }

  return true;
}

/////////////////////////////////////////////////////////////////
//
//  main()
//
/////////////////////////////////////////////////////////////////

/** Data about an acceptor.

    This is used to separate setting up the proxy ports and
    starting to accept on them.

*/
struct HttpProxyAcceptor {
  /// Accept continuation.
  Continuation *_accept = nullptr;
  /// Options for @c NetProcessor.
  NetProcessor::AcceptOptions _net_opt;

  /// Default constructor.
  HttpProxyAcceptor() {}
};

/** Global acceptors.

    This is parallel to @c HttpProxyPort::global(), each generated
    from the corresponding port descriptor.

    @internal We use @c Continuation instead of @c HttpAccept because
    @c SSLNextProtocolAccept is a subclass of @c Cont instead of @c
    HttpAccept.
*/
std::vector<HttpProxyAcceptor> HttpProxyAcceptors;

// Called from InkAPI.cc
NetProcessor::AcceptOptions
make_net_accept_options(const HttpProxyPort *port, unsigned nthreads)
{
  NetProcessor::AcceptOptions net;

  net.accept_threads = nthreads;

  REC_ReadConfigInteger(net.packet_mark, "proxy.config.net.sock_packet_mark_in");
  REC_ReadConfigInteger(net.packet_tos, "proxy.config.net.sock_packet_tos_in");
  REC_ReadConfigInteger(net.recv_bufsize, "proxy.config.net.sock_recv_buffer_size_in");
  REC_ReadConfigInteger(net.send_bufsize, "proxy.config.net.sock_send_buffer_size_in");
  REC_ReadConfigInteger(net.sockopt_flags, "proxy.config.net.sock_option_flag_in");
  REC_ReadConfigInteger(net.defer_accept, "proxy.config.net.defer_accept");

#ifdef TCP_FASTOPEN
  REC_ReadConfigInteger(net.tfo_queue_length, "proxy.config.net.sock_option_tfo_queue_size_in");
#endif

  if (port) {
    net.f_inbound_transparent = port->m_inbound_transparent_p;
    net.f_mptcp               = port->m_mptcp;
    net.ip_family             = port->m_family;
    net.local_port            = port->m_port;
    net.f_proxy_protocol      = port->m_proxy_protocol;

    if (port->m_inbound_ip.isValid()) {
      net.local_ip = port->m_inbound_ip;
    } else if (AF_INET6 == port->m_family && HttpConfig::m_master.inbound_ip6.isIp6()) {
      net.local_ip = HttpConfig::m_master.inbound_ip6;
    } else if (AF_INET == port->m_family && HttpConfig::m_master.inbound_ip4.isIp4()) {
      net.local_ip = HttpConfig::m_master.inbound_ip4;
    }
  }
  return net;
}

static void
MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort &port, unsigned nthreads)
{
  NetProcessor::AcceptOptions &net_opt = acceptor._net_opt;
  HttpSessionAccept::Options accept_opt;

  net_opt = make_net_accept_options(&port, nthreads);

  accept_opt.f_outbound_transparent = port.m_outbound_transparent_p;
  accept_opt.transport_type         = port.m_type;
  accept_opt.setHostResPreference(port.m_host_res_preference);
  accept_opt.setTransparentPassthrough(port.m_transparent_passthrough);
  accept_opt.setSessionProtocolPreference(port.m_session_protocol_preference);

  if (port.m_outbound_ip4.isValid()) {
    accept_opt.outbound_ip4 = port.m_outbound_ip4;
  } else if (HttpConfig::m_master.outbound_ip4.isValid()) {
    accept_opt.outbound_ip4 = HttpConfig::m_master.outbound_ip4;
  }

  if (port.m_outbound_ip6.isValid()) {
    accept_opt.outbound_ip6 = port.m_outbound_ip6;
  } else if (HttpConfig::m_master.outbound_ip6.isValid()) {
    accept_opt.outbound_ip6 = HttpConfig::m_master.outbound_ip6;
  }

  // OK the way this works is that the fallback for each port is a protocol
  // probe acceptor. For SSL ports, we can stack a NPN+ALPN acceptor in front
  // of that, and these ports will fall back to the probe if no NPN+ALPN endpoint
  // was negotiated.

  // XXX the protocol probe should be a configuration option.

  ProtocolProbeSessionAccept *probe = new ProtocolProbeSessionAccept();
  HttpSessionAccept *http           = nullptr; // don't allocate this unless it will be used.
  probe->proxyPort                  = &port;
  probe->proxy_protocol_ipmap       = &HttpConfig::m_master.config_proxy_protocol_ipmap;

  if (port.m_session_protocol_preference.intersects(HTTP_PROTOCOL_SET)) {
    http = new HttpSessionAccept(accept_opt);
    probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP, http);
  }

  if (port.m_session_protocol_preference.intersects(HTTP2_PROTOCOL_SET)) {
    probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP2, new Http2SessionAccept(accept_opt));
  }

  if (port.isSSL()) {
    SSLNextProtocolAccept *ssl = new SSLNextProtocolAccept(probe, port.m_transparent_passthrough);

    // ALPN selects the first server-offered protocol,
    // so make sure that we offer the newest protocol first.
    // But since registerEndpoint prepends you want to
    // register them backwards, so you'd want to register
    // the least important protocol first:
    // http/1.0, http/1.1, h2

    ssl->enableProtocols(port.m_session_protocol_preference);
    ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_1_0, http);
    ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_1_1, http);
    ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_2_0, new Http2SessionAccept(accept_opt));

    SCOPED_MUTEX_LOCK(lock, ssl_plugin_mutex, this_ethread());
    ssl_plugin_acceptors.push(ssl);
    ssl->proxyPort   = &port;
    acceptor._accept = ssl;
#if TS_USE_QUIC == 1
  } else if (port.isQUIC()) {
    QUICNextProtocolAccept *quic = new QUICNextProtocolAccept();

    quic->enableProtocols(port.m_session_protocol_preference);

    // HTTP/0.9 over QUIC draft-27 (for interop only, will be removed)
    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC_D27, new Http3SessionAccept(accept_opt));

    // HTTP/3 draft-27
    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_3_D27, new Http3SessionAccept(accept_opt));

    // HTTP/0.9 over QUIC (for interop only, will be removed)
    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC, new Http3SessionAccept(accept_opt));

    // HTTP/3
    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_3, new Http3SessionAccept(accept_opt));

    quic->proxyPort  = &port;
    acceptor._accept = quic;
#endif
  } else {
    acceptor._accept = probe;
  }
}

/// Do all pre-thread initialization / setup.
void
prep_HttpProxyServer()
{
  httpSessionManager.init();
}

/** Set up all the accepts and sockets.
 */
void
init_accept_HttpProxyServer(int n_accept_threads)
{
  HttpProxyPort::Group &proxy_ports = HttpProxyPort::global();

  init_reverse_proxy();
  http_pages_init();

#ifdef USE_HTTP_DEBUG_LISTS
  ink_mutex_init(&debug_sm_list_mutex);
  ink_mutex_init(&debug_cs_list_mutex);
#endif

  // Used to give plugins the ability to create http requests
  //   The equivalent of the connecting to localhost on the  proxy
  //   port but without going through the operating system
  //
  if (plugin_http_accept == nullptr) {
    plugin_http_accept = new HttpSessionAccept();
  }

  // Same as plugin_http_accept except outbound transparent.
  if (!plugin_http_transparent_accept) {
    HttpSessionAccept::Options ha_opt;
    ha_opt.setOutboundTransparent(true);
    plugin_http_transparent_accept = new HttpSessionAccept(ha_opt);
  }

  if (!ssl_plugin_mutex) {
    ssl_plugin_mutex = new_ProxyMutex();
  }

  // Do the configuration defined ports.
  // Assign temporary empty objects of proxy ports size
  HttpProxyAcceptors.assign(proxy_ports.size(), HttpProxyAcceptor());
  for (int i = 0, n = proxy_ports.size(); i < n; ++i) {
    MakeHttpProxyAcceptor(HttpProxyAcceptors.at(i), proxy_ports[i], n_accept_threads);
  }
}

/** Increment the counter to keep track of how many et_net threads
 *  we have started. This function is scheduled at the start of each
 *  et_net thread using schedule_spawn(). We also check immediately
 *  after incrementing the counter to see whether all of the et_net
 *  threads have started such that we can notify main() to call
 *  start_HttpProxyServer().
 */
void
init_HttpProxyServer()
{
  if (eventProcessor.has_tg_started(ET_NET)) {
    std::unique_lock<std::mutex> lock(proxyServerMutex);
    et_net_threads_ready = true;
    lock.unlock();
    proxyServerCheck.notify_one();
  }

#if TS_USE_QUIC == 1
  if (eventProcessor.has_tg_started(ET_UDP)) {
    std::unique_lock<std::mutex> lock(etUdpMutex);
    et_udp_threads_ready = true;
    lock.unlock();
    etUdpCheck.notify_one();
  }
#endif
}

void
start_HttpProxyServer()
{
  static bool called_once           = false;
  HttpProxyPort::Group &proxy_ports = HttpProxyPort::global();

  ///////////////////////////////////
  // start accepting connections   //
  ///////////////////////////////////

  ink_assert(!called_once);
  ink_assert(proxy_ports.size() == HttpProxyAcceptors.size());

  for (int i = 0, n = proxy_ports.size(); i < n; ++i) {
    HttpProxyAcceptor &acceptor = HttpProxyAcceptors[i];
    HttpProxyPort &port         = proxy_ports[i];
    if (port.isSSL()) {
      if (nullptr == sslNetProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt)) {
        return;
      }
#if TS_USE_QUIC == 1
    } else if (port.isQUIC()) {
      if (nullptr == quic_NetProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt)) {
        return;
      }
#endif
    } else if (!port.isPlugin()) {
      if (nullptr == netProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt)) {
        return;
      }
    }
    // XXX although we make a good pretence here, I don't believe that NetProcessor::main_accept() ever actually returns
    // NULL. It would be useful to be able to detect errors and spew them here though.
  }

  // Set up stat page for http connection count
  statPagesManager.register_http("connection_count", register_ShowConnectionCount);

  // Alert plugins that connections will be accepted.
  APIHook *hook = lifecycle_hooks->get(TS_LIFECYCLE_PORTS_READY_HOOK);
  while (hook) {
    hook->invoke(TS_EVENT_LIFECYCLE_PORTS_READY, nullptr);
    hook = hook->next();
  }
}

void
stop_HttpProxyServer()
{
  sslNetProcessor.stop_accept();
  netProcessor.stop_accept();
}
