/** @file

  ProxySession - Base class for protocol client sessions.

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

#pragma once

#include "tscore/ink_platform.h"
#include "tscore/ink_resolver.h"
#include "tscore/TSSystemState.h"
#include <string_view>
#include <memory>
#include "P_Net.h"
#include "InkAPIInternal.h"
#include "http/HttpSessionAccept.h"
#include "IPAllow.h"
#include "private/SSLProxySession.h"

// Emit a debug message conditional on whether this particular client session
// has debugging enabled. This should only be called from within a client session
// member function.
#define SsnDebug(ssn, tag, ...) SpecificDebug((ssn)->debug(), tag, __VA_ARGS__)

class ProxyTransaction;
class PoolableSession;

enum class ProxyErrorClass {
  NONE,
  SSN,
  TXN,
};

struct ProxyError {
  ProxyError() {}
  ProxyError(ProxyErrorClass cl, uint32_t co) : cls(cl), code(co) {}
  size_t
  str(char *buf, size_t buf_len) const
  {
    size_t len = 0;

    if (this->cls == ProxyErrorClass::NONE) {
      buf[0] = '-';
      return 1;
    }

    buf[0] = (this->cls == ProxyErrorClass::SSN) ? 'S' : 'T';
    ++len;

    len += snprintf(buf + len, buf_len - len, "%" PRIx32, this->code);

    return len;
  }

  ProxyErrorClass cls = ProxyErrorClass::NONE;
  uint32_t code       = 0;
};

/// Abstract class for HttpSM to interface with any session
class ProxySession : public VConnection, public PluginUserArgs<TS_USER_ARGS_SSN>
{
public:
  ProxySession();
  ProxySession(NetVConnection *vc);
  virtual ~ProxySession();

  // noncopyable
  ProxySession(ProxySession &) = delete;
  ProxySession &operator=(const ProxySession &) = delete;

  static int64_t next_connection_id();

  // Virtual Methods
  virtual void new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader) = 0;
  virtual void start()                                                                          = 0;
  virtual bool attach_server_session(PoolableSession *ssession, bool transaction_done = true);

  virtual void release(ProxyTransaction *trans) = 0;

  virtual void destroy() = 0;
  virtual void free()    = 0;

  virtual void increment_current_active_connections_stat() = 0;
  virtual void decrement_current_active_connections_stat() = 0;

  // Virtual Accessors
  virtual int get_transact_count() const          = 0;
  virtual const char *get_protocol_string() const = 0;

  virtual void hook_add(TSHttpHookID id, INKContInternal *cont);

  virtual bool is_chunked_encoding_supported() const;
  virtual void set_half_close_flag(bool flag);
  virtual bool get_half_close_flag() const;

  virtual PoolableSession *get_server_session() const;

  // Replicate NetVConnection API
  virtual sockaddr const *get_remote_addr() const;
  virtual sockaddr const *get_local_addr();

  virtual void set_active_timeout(ink_hrtime timeout_in);
  virtual void set_inactivity_timeout(ink_hrtime timeout_in);
  virtual void cancel_inactivity_timeout();
  virtual void cancel_active_timeout();

  virtual int populate_protocol(std::string_view *result, int size) const;
  virtual const char *protocol_contains(std::string_view tag_prefix) const;
  virtual HTTPVersion get_version(HTTPHdr &hdr) const;

  // Non-Virtual Methods
  NetVConnection *get_netvc() const;
  int do_api_callout(TSHttpHookID id);

  void set_debug(bool flag);
  bool debug() const;

  void set_session_active();
  void clear_session_active();
  bool is_active() const;
  bool is_draining() const;
  bool is_peer_closed() const;

  int64_t connection_id() const;
  TSHttpHookID get_hookid() const;
  bool has_hooks() const;

  virtual bool support_sni() const;

  APIHook *hook_get(TSHttpHookID id) const;
  HttpAPIHooks const *feature_hooks() const;

  // Returns null pointer if session does not use a TLS connection.
  SSLProxySession const *ssl() const;

  // Implement VConnection interface
  VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX, MIOBuffer *buf = nullptr) override;
  VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = 0, bool owner = false) override;
  void do_io_shutdown(ShutdownHowTo_t howto) override;
  void reenable(VIO *vio) override;

  virtual ProxyTransaction *
  new_transaction()
  {
    return nullptr;
  }

  ////////////////////
  // Members

  IpAllow::ACL acl; ///< IpAllow based method ACL.

  HttpSessionAccept::Options const *accept_options; ///< connection info // L7R TODO: set in constructor

protected:
  // Hook dispatching state
  HttpHookState hook_state;

  // XXX Consider using a bitwise flags variable for the following flags, so
  // that we can make the best use of internal alignment padding.

  // Session specific debug flag.
  bool debug_on   = false;
  bool in_destroy = false;

  int64_t con_id        = 0;
  Event *schedule_event = nullptr;

  // This function should be called in all overrides of new_connection() where
  // the new_vc may be an SSLNetVConnection object.
  void _handle_if_ssl(NetVConnection *new_vc);

  NetVConnection *_vc = nullptr; // The netvc associated with the concrete session class

private:
  void handle_api_return(int event);
  int state_api_callout(int event, void *edata);

  APIHook const *cur_hook = nullptr;
  HttpAPIHooks api_hooks;

  // for DI. An active connection is one that a request has
  // been successfully parsed (PARSE_DONE) and it remains to
  // be active until the transaction goes through or the client
  // aborts.
  bool m_active = false;

  std::unique_ptr<SSLProxySession> _ssl;
  static inline int64_t next_cs_id = 0;
};

///////////////////
// INLINE

inline int64_t
ProxySession::next_connection_id()
{
  return ink_atomic_increment(&next_cs_id, 1);
}

inline void
ProxySession::set_debug(bool flag)
{
  debug_on = flag;
}

// Return whether debugging is enabled for this session.
inline bool
ProxySession::debug() const
{
  return this->debug_on;
}

inline bool
ProxySession::is_active() const
{
  return m_active;
}

inline bool
ProxySession::is_draining() const
{
  return TSSystemState::is_draining();
}

inline bool
ProxySession::is_peer_closed() const
{
  return get_netvc() == nullptr;
}

inline TSHttpHookID
ProxySession::get_hookid() const
{
  return hook_state.id();
}

inline void
ProxySession::hook_add(TSHttpHookID id, INKContInternal *cont)
{
  this->api_hooks.append(id, cont);
}

inline APIHook *
ProxySession::hook_get(TSHttpHookID id) const
{
  return this->api_hooks.get(id);
}

inline HttpAPIHooks const *
ProxySession::feature_hooks() const
{
  return &api_hooks;
}

inline bool
ProxySession::has_hooks() const
{
  return this->api_hooks.has_hooks() || http_global_hooks->has_hooks();
}

inline SSLProxySession const *
ProxySession::ssl() const
{
  return _ssl.get();
}

inline NetVConnection *
ProxySession::get_netvc() const
{
  return _vc;
}
