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

#pragma once

#include <string_view>
#include <chrono>
#include <atomic>
#include <sstream>
#include <tuple>
#include <mutex>
#include "tscore/ink_platform.h"
#include "tscore/ink_config.h"
#include "tscore/ink_mutex.h"
#include "tscore/ink_inet.h"
#include "tscore/IntrusiveHashMap.h"
#include "tscore/Diags.h"
#include "tscore/CryptoHash.h"
#include "tscore/BufferWriterForward.h"
#include "tscpp/util/TextView.h"
#include <MgmtDefs.h>
#include "HttpProxyAPIEnums.h"
#include "Show.h"

/**
 * Singleton class to keep track of the number of outbound connections.
 *
 * Outbound connections are divided in to equivalence classes (called "groups" here) based on the
 * session matching setting. Tracking data is stored for each group.
 */
class OutboundConnTrack
{
  using self_type = OutboundConnTrack; ///< Self reference type.

public:
  // Non-copyable.
  OutboundConnTrack(const self_type &) = delete;
  self_type &operator=(const self_type &) = delete;

  /// Definition of an upstream server group equivalence class.
  enum MatchType {
    MATCH_IP   = TS_SERVER_OUTBOUND_MATCH_IP,   ///< Match by IP address.
    MATCH_PORT = TS_SERVER_OUTBOUND_MATCH_PORT, ///< Match by IP address and port.
    MATCH_HOST = TS_SERVER_OUTBOUND_MATCH_HOST, ///< Match by hostname (FQDN).
    MATCH_BOTH = TS_SERVER_OUTBOUND_MATCH_BOTH, ///< Hostname, IP Address and port.
  };

  /// String equivalents for @c MatchType.
  static const std::array<std::string_view, static_cast<int>(MATCH_BOTH) + 1> MATCH_TYPE_NAME;

  /// Per transaction configuration values.
  struct TxnConfig {
    int max{0};                ///< Maximum concurrent connections.
    int min{0};                ///< Minimum keepalive connections.
    MatchType match{MATCH_IP}; ///< Match type.
  };

  /** Static configuration values. */
  struct GlobalConfig {
    std::chrono::seconds alert_delay{60}; ///< Alert delay in seconds.
  };

  // The names of the configuration values.
  // Unfortunately these are not used in RecordsConfig.cc so that must be made consistent by hand.
  // Note: These need to be @c constexpr or there are static initialization ordering risks.
  static constexpr std::string_view CONFIG_VAR_MAX{"proxy.config.http.per_server.connection.max"_sv};
  static constexpr std::string_view CONFIG_VAR_MIN{"proxy.config.http.per_server.connection.min"_sv};
  static constexpr std::string_view CONFIG_VAR_MATCH{"proxy.config.http.per_server.connection.match"_sv};
  static constexpr std::string_view CONFIG_VAR_ALERT_DELAY{"proxy.config.http.per_server.connection.alert_delay"_sv};

  /// A record for the outbound connection count.
  /// These are stored per outbound session equivalence class, as determined by the session matching.
  struct Group {
    /// Base clock.
    using Clock = std::chrono::system_clock;
    /// Time point type, based on the clock to be used.
    using TimePoint = Clock::time_point;
    /// Raw type for clock / time point counts.
    using Ticker = TimePoint::rep;
    /// Length of time to suppress alerts for a group.
    static const std::chrono::seconds ALERT_DELAY;

    /// Equivalence key - two groups are equivalent if their keys are equal.
    struct Key {
      IpEndpoint const &_addr;      ///< Remote IP address.
      CryptoHash const &_hash;      ///< Hash of the FQDN.
      MatchType const &_match_type; ///< Type of matching.
    };

    IpEndpoint _addr;         ///< Remote IP address.
    CryptoHash _hash;         ///< Hash of the FQDN.
    MatchType _match_type;    ///< Type of matching.
    std::string _fqdn;        ///< Expanded FQDN, set if matching on FQDN.
    int min_keep_alive_conns; /// < Min keep alive conns on this server group
    Key _key;                 ///< Pre-assembled key which references the following members.

    // Counting data.
    std::atomic<int> _count{0};         ///< Number of outbound connections.
    std::atomic<int> _count_max{0};     ///< largest observed @a count value.
    std::atomic<int> _blocked{0};       ///< Number of outbound connections blocked since last alert.
    std::atomic<int> _in_queue{0};      ///< # of connections queued, waiting for a connection.
    std::atomic<Ticker> _last_alert{0}; ///< Absolute time of the last alert.

    // Links for intrusive container.
    Group *_next{nullptr};
    Group *_prev{nullptr};

    /** Constructor.
     * Construct from @c Key because the use cases do a table lookup first so the @c Key is already constructed.
     * @param key A populated @c Key structure - values are copied to the @c Group.
     * @param fqdn The full FQDN.
     */
    Group(Key const &key, std::string_view fqdn, int min_keep_alive);
    /// Key equality checker.
    static bool equal(Key const &lhs, Key const &rhs);
    /// Hashing function.
    static uint64_t hash(Key const &);
    /// Check and clear alert enable.
    /// This is a modifying call - internal state will be updated to prevent too frequent alerts.
    /// @param lat The last alert time, in epoch seconds, if the method returns @c true.
    /// @return @c true if an alert should be generated, @c false otherwise.
    bool should_alert(std::time_t *lat = nullptr);
    /// Time of the last alert in epoch seconds.
    std::time_t get_last_alert_epoch_time() const;
  };

  /// Container for per transaction state and operations.
  struct TxnState {
    Group *_g{nullptr};      ///< Active group for this transaction.
    bool _reserved_p{false}; ///< Set if a connection slot has been reserved.
    bool _queued_p{false};   ///< Set if the connection is delayed / queued.

    /// Check if tracking is active.
    bool is_active();

    /// Reserve a connection.
    int reserve();
    /// Release a connection reservation.
    void release();
    /// Reserve a queue / retry slot.
    int enqueue();
    /// Release a block
    void dequeue();
    /// Note blocking a transaction.
    void blocked();
    /// Clear all reservations.
    void clear();
    /// Drop the reservation - assume it will be cleaned up elsewhere.
    /// @return The group for this reservation.
    Group *drop();
    /// Update the maximum observed count if needed against @a count.
    void update_max_count(int count);

    /** Generate a Notice that the group has become unblocked.
     *
     * @param config Transaction local configuration.
     * @param count Current connection count for display in message.
     * @param addr IP address of the upstream.
     */
    void Note_Unblocked(const TxnConfig *config, int count, const sockaddr *addr);

    /** Generate a Warning that a connection was blocked.
     *
     * @param config Transaction local configuration.
     * @param sm_id State machine ID to display in Warning.
     * @param count Count value to display in Warning.
     * @param addr IP address of the upstream.
     * @param debug_tag Tag to use for the debug message. If no debug message should be generated set this to @c nullptr.
     */
    void Warn_Blocked(const TxnConfig *config, int64_t sm_id, int count, const sockaddr *addr, const char *debug_tag = nullptr);
  };

  /** Get or create the @c Group for the specified session properties.
   * @param txn_cnf The transaction local configuration.
   * @param fqdn The fully qualified domain name of the upstream.
   * @param addr The IP address of the upstream.
   * @return A @c Group for the arguments, existing if possible and created if not.
   */
  static TxnState obtain(TxnConfig const &txn_cnf, std::string_view fqdn, const IpEndpoint &addr);

  /** Get the currently existing groups.
   * @param [out] groups parameter - pointers to the groups are pushed in to this container.
   *
   * The groups are loaded in to @a groups, which is cleared before loading. Note the groups returned will remain valid
   * although data inside the groups is volatile.
   */
  static void get(std::vector<Group const *> &groups);
  /** Write the connection tracking data to JSON.
   * @return string containing a JSON encoding of the table.
   */
  static std::string to_json_string();
  /** Write the groups to @a f.
   * @param f Output file.
   */
  static void dump(FILE *f);
  /** Do global initialization.
   *
   * This sets up the global configuration and any configuration update callbacks needed. It is presumed
   * the caller has set up the actual storage where the global configuration data is stored.
   *
   * @param config The storage for the global configuration data.
   * @param txn The storage for the default per transaction data.
   */
  static void config_init(GlobalConfig *global, TxnConfig *txn);

  /// Tag used for debugging output.
  static constexpr char const *const DEBUG_TAG{"conn_track"};

  /** Convert a string to a match type.
   *
   * @a type is updated only if this method returns @c true.
   *
   * @param [in] tag Tag to look up.
   * @param [out] type Resulting type.
   * @return @c true if @a tag was valid and @a type was updated, otherwise @c false.
   */
  static bool lookup_match_type(std::string_view tag, MatchType &type);

  /** Generate a warning message for a bad @c MatchType tag.
   *
   * @param tag The invalid tag.
   */
  static void Warning_Bad_Match_Type(std::string_view tag);

  // Converters for overridable values for use in the TS API.
  static const MgmtConverter MIN_CONV;
  static const MgmtConverter MAX_CONV;
  static const MgmtConverter MATCH_CONV;

protected:
  static GlobalConfig *_global_config; ///< Global configuration data.

  /// Types and methods for the hash table.
  struct Linkage {
    using key_type   = Group::Key const &;
    using value_type = Group;

    static value_type *&next_ptr(value_type *value);
    static value_type *&prev_ptr(value_type *value);

    static uint64_t hash_of(key_type key);

    static key_type key_of(value_type *v);

    static bool equal(key_type lhs, key_type rhs);
  };

  /// Internal implementation class instance.
  struct Imp {
    IntrusiveHashMap<Linkage> _table; ///< Hash table of upstream groups.
    std::mutex _mutex;                ///< Lock for insert & find.
  };
  static Imp _imp;

  /// Get the implementation instance.
  /// @note This is done purely to allow subclasses to reuse methods in this class.
  Imp &instance();
};

inline OutboundConnTrack::Imp &
OutboundConnTrack::instance()
{
  return _imp;
}

inline OutboundConnTrack::Group::Group(Key const &key, std::string_view fqdn, int min_keep_alive)
  : _hash(key._hash), _match_type(key._match_type), min_keep_alive_conns(min_keep_alive), _key{_addr, _hash, _match_type}
{
  // store the host name if relevant.
  if (MATCH_HOST == _match_type || MATCH_BOTH == _match_type) {
    _fqdn.assign(fqdn);
  }
  // store the IP address if relevant.
  if (MATCH_HOST == _match_type) {
    _addr.setToAnyAddr(AF_INET);
  } else {
    ats_ip_copy(_addr, key._addr);
  }
}

inline uint64_t
OutboundConnTrack::Group::hash(const Key &key)
{
  switch (key._match_type) {
  case MATCH_IP:
    return ats_ip_hash(&key._addr.sa);
  case MATCH_PORT:
    return ats_ip_port_hash(&key._addr.sa);
  case MATCH_HOST:
    return key._hash.fold();
  case MATCH_BOTH:
    return ats_ip_port_hash(&key._addr.sa) ^ key._hash.fold();
  default:
    return 0;
  }
}

inline bool
OutboundConnTrack::TxnState::is_active()
{
  return nullptr != _g;
}

inline int
OutboundConnTrack::TxnState::reserve()
{
  _reserved_p = true;
  return ++_g->_count;
}

inline void
OutboundConnTrack::TxnState::release()
{
  if (_reserved_p) {
    _reserved_p = false;
    --_g->_count;
  }
}

inline OutboundConnTrack::Group *
OutboundConnTrack::TxnState::drop()
{
  _reserved_p = false;
  return _g;
}

inline int
OutboundConnTrack::TxnState::enqueue()
{
  _queued_p = true;
  return ++_g->_in_queue;
}

inline void
OutboundConnTrack::TxnState::dequeue()
{
  if (_queued_p) {
    _queued_p = false;
    --_g->_in_queue;
  }
}

inline void
OutboundConnTrack::TxnState::clear()
{
  if (_g) {
    this->dequeue();
    this->release();
    _g = nullptr;
  }
}

inline void
OutboundConnTrack::TxnState::update_max_count(int count)
{
  auto cmax = _g->_count_max.load();
  if (count > cmax) {
    _g->_count_max.compare_exchange_weak(cmax, count);
  }
}

inline void
OutboundConnTrack::TxnState::blocked()
{
  ++_g->_blocked;
}

/* === Linkage === */
inline auto
OutboundConnTrack::Linkage::next_ptr(value_type *value) -> value_type *&
{
  return value->_next;
}

inline auto
OutboundConnTrack::Linkage::prev_ptr(value_type *value) -> value_type *&
{
  return value->_prev;
}

inline uint64_t
OutboundConnTrack::Linkage::hash_of(key_type key)
{
  return Group::hash(key);
}

inline auto
OutboundConnTrack::Linkage::key_of(value_type *value) -> key_type
{
  return value->_key;
}

inline bool
OutboundConnTrack::Linkage::equal(key_type lhs, key_type rhs)
{
  return Group::equal(lhs, rhs);
}
/* === */

Action *register_ShowConnectionCount(Continuation *, HTTPHdr *);

namespace ts
{
BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, OutboundConnTrack::MatchType type);
BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, OutboundConnTrack::Group::Key const &key);
BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, OutboundConnTrack::Group const &g);
} // namespace ts
