/** @file

  PoolableSession - class that extends ProxySession so that they can be cataloged for reuse.

  @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 <memory>

#include "iocore/net/ConnectionTracker.h"
#include "proxy/ProxySession.h"

class PoolableSession : public ProxySession
{
  using self_type  = PoolableSession;
  using super_type = ProxySession;

public:
  enum class PooledState {
    INIT,
    SSN_IN_USE,    // actively in use
    KA_RESERVED,   // stuck to client
    KA_POOLED,     // free for reuse
    SSN_CLOSED,    // Session ready to be freed
    SSN_TO_RELEASE // Session reaady to be released
  };

  /// Hash map descriptor class for IP map.
  struct IPLinkage {
    self_type *_next = nullptr;
    self_type *_prev = nullptr;

    static self_type     *&next_ptr(self_type *);
    static self_type     *&prev_ptr(self_type *);
    static uint32_t        hash_of(sockaddr const *key);
    static sockaddr const *key_of(self_type const *ssn);
    static bool            equal(sockaddr const *lhs, sockaddr const *rhs);
    // Add a couple overloads for internal convenience.
    static bool equal(sockaddr const *lhs, PoolableSession const *rhs);
    static bool equal(PoolableSession const *lhs, sockaddr const *rhs);
  } _ip_link;

  /// Hash map descriptor class for FQDN map.
  struct FQDNLinkage {
    self_type *_next = nullptr;
    self_type *_prev = nullptr;

    static self_type       *&next_ptr(self_type *);
    static self_type       *&prev_ptr(self_type *);
    static uint64_t          hash_of(CryptoHash const &key);
    static CryptoHash const &key_of(self_type *ssn);
    static bool              equal(CryptoHash const &lhs, CryptoHash const &rhs);
  } _fqdn_link;

  CryptoHash  hostname_hash;
  PooledState state = PooledState::INIT;

  // Copy of the owning SM's server session sharing settings
  TSServerSessionSharingMatchMask sharing_match = TS_SERVER_SESSION_SHARING_MATCH_MASK_NONE;
  TSServerSessionSharingPoolType  sharing_pool  = TS_SERVER_SESSION_SHARING_POOL_GLOBAL;

  void enable_outbound_connection_tracking(std::shared_ptr<ConnectionTracker::Group> group);
  void release_outbound_connection_tracking();

  void attach_hostname(const char *hostname);

  void set_active();
  bool is_active();
  void set_private(bool new_private = true);
  bool is_private() const;

  virtual void set_netvc(NetVConnection *newvc);
  virtual bool is_multiplexing() const;

  // Keep track of connection limiting and a pointer to the
  // singleton that keeps track of the connection counts.
  std::shared_ptr<ConnectionTracker::Group> conn_track_group;

  virtual IOBufferReader *get_remote_reader() = 0;

  // Used to determine whether the session is for parent proxy
  // it is session to origin server
  // We need to determine whether a closed connection was to
  // close parent proxy to update the
  // proxy.process.http.current_parent_proxy_connections
  bool to_parent_proxy = false;

private:
  // Sessions become if authentication headers
  //  are sent over them
  bool private_session = false;
};

inline void
PoolableSession::set_active()
{
  state = PooledState::SSN_IN_USE;
}
inline bool
PoolableSession::is_active()
{
  return state == PooledState::SSN_IN_USE;
}
inline void
PoolableSession::set_private(bool new_private)
{
  private_session = new_private;
}
inline bool
PoolableSession::is_private() const
{
  return private_session;
}

inline void
PoolableSession::set_netvc(NetVConnection *newvc)
{
  ProxySession::_vc = newvc;
}

//
// LINKAGE

inline PoolableSession *&
PoolableSession::IPLinkage::next_ptr(self_type *ssn)
{
  return ssn->_ip_link._next;
}

inline PoolableSession *&
PoolableSession::IPLinkage::prev_ptr(self_type *ssn)
{
  return ssn->_ip_link._prev;
}

inline uint32_t
PoolableSession::IPLinkage::hash_of(sockaddr const *key)
{
  return ats_ip_hash(key);
}

inline sockaddr const *
PoolableSession::IPLinkage::key_of(self_type const *ssn)
{
  return ssn->get_remote_addr();
}

inline bool
PoolableSession::IPLinkage::equal(sockaddr const *lhs, sockaddr const *rhs)
{
  return ats_ip_addr_port_eq(lhs, rhs);
}

inline bool
PoolableSession::IPLinkage::equal(sockaddr const *lhs, PoolableSession const *rhs)
{
  return ats_ip_addr_port_eq(lhs, key_of(rhs));
}

inline bool
PoolableSession::IPLinkage::equal(PoolableSession const *lhs, sockaddr const *rhs)
{
  return ats_ip_addr_port_eq(key_of(lhs), rhs);
}

inline PoolableSession *&
PoolableSession::FQDNLinkage::next_ptr(self_type *ssn)
{
  return ssn->_fqdn_link._next;
}

inline PoolableSession *&
PoolableSession::FQDNLinkage::prev_ptr(self_type *ssn)
{
  return ssn->_fqdn_link._prev;
}

inline uint64_t
PoolableSession::FQDNLinkage::hash_of(CryptoHash const &key)
{
  return key.fold();
}

inline CryptoHash const &
PoolableSession::FQDNLinkage::key_of(self_type *ssn)
{
  return ssn->hostname_hash;
}

inline bool
PoolableSession::FQDNLinkage::equal(CryptoHash const &lhs, CryptoHash const &rhs)
{
  return lhs == rhs;
}

inline void
PoolableSession::enable_outbound_connection_tracking(std::shared_ptr<ConnectionTracker::Group> group)
{
  ink_assert(nullptr == conn_track_group);
  conn_track_group = std::move(group);
}

inline void
PoolableSession::release_outbound_connection_tracking()
{
  // Update upstream connection tracking data if present.
  if (conn_track_group) {
    conn_track_group->release();
    conn_track_group.reset();
  }
}

inline void
PoolableSession::attach_hostname(const char *hostname)
{
  if (hostname_hash.is_zero()) {
    CryptoContext().hash_immediate(hostname_hash, static_cast<const unsigned char *>(static_cast<const void *>(hostname)),
                                   strlen(hostname));
  }
}

inline bool
PoolableSession::is_multiplexing() const
{
  return false;
}
