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

/****************************************************************************
  P_HostDBProcessor.h
 ****************************************************************************/

#pragma once

#include "I_HostDBProcessor.h"
#include "tscore/TsBuffer.h"

//
// Data
//

extern int hostdb_enable;
extern int hostdb_migrate_on_demand;
extern int hostdb_lookup_timeout;
extern int hostdb_insert_timeout;
extern int hostdb_re_dns_on_reload;

// 0 = obey, 1 = ignore, 2 = min(X,ttl), 3 = max(X,ttl)
enum {
  TTL_OBEY,
  TTL_IGNORE,
  TTL_MIN,
  TTL_MAX,
};

extern int hostdb_ttl_mode;
extern int hostdb_srv_enabled;

// extern int hostdb_timestamp;
extern int hostdb_sync_frequency;
extern int hostdb_disable_reverse_lookup;

// Static configuration information
extern HostDBCache hostDB;

/** Host DB record mark.

    The records in the host DB are de facto segregated by roughly the
    DNS query type. We use an intermediate type to provide a little flexibility
    although the type is presumed to be a single byte.
 */
enum HostDBMark {
  HOSTDB_MARK_GENERIC, ///< Anything that's not one of the other types.
  HOSTDB_MARK_IPV4,    ///< IPv4 / T_A
  HOSTDB_MARK_IPV6,    ///< IPv6 / T_AAAA
  HOSTDB_MARK_SRV,     ///< Service / T_SRV
};
/** Convert a HostDB @a mark to a string.
    @return A static string.
 */
extern const char *string_for(HostDBMark mark);

inline unsigned int
HOSTDB_CLIENT_IP_HASH(sockaddr const *lhs, sockaddr const *rhs)
{
  unsigned int zret = ~static_cast<unsigned int>(0);
  if (ats_ip_are_compatible(lhs, rhs)) {
    if (ats_is_ip4(lhs)) {
      in_addr_t ip1 = ats_ip4_addr_cast(lhs);
      in_addr_t ip2 = ats_ip4_addr_cast(rhs);
      zret          = (ip1 >> 16) ^ ip1 ^ ip2 ^ (ip2 >> 16);
    } else if (ats_is_ip6(lhs)) {
      uint32_t const *ip1 = ats_ip_addr32_cast(lhs);
      uint32_t const *ip2 = ats_ip_addr32_cast(rhs);
      for (int i = 0; i < 4; ++i, ++ip1, ++ip2) {
        zret ^= (*ip1 >> 16) ^ *ip1 ^ *ip2 ^ (*ip2 >> 16);
      }
    }
  }
  return zret & 0xFFFF;
}

//
// Constants
//

#define HOST_DB_HITS_BITS 3
#define HOST_DB_TAG_BITS 56

#define CONFIGURATION_HISTORY_PROBE_DEPTH 1

// Bump this any time hostdb format is changed
#define HOST_DB_CACHE_MAJOR_VERSION 3
#define HOST_DB_CACHE_MINOR_VERSION 0
// 2.2: IP family split 2.1 : IPv6

#define DEFAULT_HOST_DB_FILENAME "host.db"
#define DEFAULT_HOST_DB_SIZE (1 << 14)
// Timeout DNS every 24 hours by default if ttl_mode is enabled
#define HOST_DB_IP_TIMEOUT (24 * 60 * 60)
// DNS entries should be revalidated every 12 hours
#define HOST_DB_IP_STALE (12 * 60 * 60)
// DNS entries which failed lookup, should be revalidated every hour
#define HOST_DB_IP_FAIL_TIMEOUT (60 * 60)

//#define HOST_DB_MAX_INTERVAL                 (0x7FFFFFFF)
const unsigned int HOST_DB_MAX_TTL = (0x1FFFFF); // 24 days

//
// Constants
//

// period to wait for a remote probe...
#define HOST_DB_RETRY_PERIOD HRTIME_MSECONDS(20)
#define HOST_DB_ITERATE_PERIOD HRTIME_MSECONDS(5)

//#define TEST(_x) _x
#define TEST(_x)

struct HostEnt;

// Stats
enum HostDB_Stats {
  hostdb_total_lookups_stat,
  hostdb_total_hits_stat,  // D == total hits
  hostdb_ttl_stat,         // D average TTL
  hostdb_ttl_expires_stat, // D == TTL Expires
  hostdb_re_dns_on_reload_stat,
  HostDB_Stat_Count
};

struct RecRawStatBlock;
extern RecRawStatBlock *hostdb_rsb;

// Stat Macros

#define HOSTDB_DEBUG_COUNT_DYN_STAT(_x, _y) RecIncrRawStatCount(hostdb_rsb, mutex->thread_holding, (int)_x, _y)

#define HOSTDB_INCREMENT_DYN_STAT(_x) RecIncrRawStatSum(hostdb_rsb, mutex->thread_holding, (int)_x, 1)

#define HOSTDB_DECREMENT_DYN_STAT(_x) RecIncrRawStatSum(hostdb_rsb, mutex->thread_holding, (int)_x, -1)

#define HOSTDB_SUM_DYN_STAT(_x, _r) RecIncrRawStatSum(hostdb_rsb, mutex->thread_holding, (int)_x, _r)

#define HOSTDB_READ_DYN_STAT(_x, _count, _sum)        \
  do {                                                \
    RecGetRawStatSum(hostdb_rsb, (int)_x, &_sum);     \
    RecGetRawStatCount(hostdb_rsb, (int)_x, &_count); \
  } while (0)

#define HOSTDB_SET_DYN_COUNT(_x, _count) RecSetRawStatCount(hostdb_rsb, _x, _count);

#define HOSTDB_INCREMENT_THREAD_DYN_STAT(_s, _t) RecIncrRawStatSum(hostdb_rsb, _t, (int)_s, 1);

#define HOSTDB_DECREMENT_THREAD_DYN_STAT(_s, _t) RecIncrRawStatSum(hostdb_rsb, _t, (int)_s, -1);

struct CmpConstBuffferCaseInsensitive {
  bool
  operator()(ts::ConstBuffer a, ts::ConstBuffer b) const
  {
    return ptr_len_casecmp(a._ptr, a._size, b._ptr, b._size) < 0;
  }
};

// Our own typedef for the host file mapping
typedef std::map<ts::ConstBuffer, IpAddr, CmpConstBuffferCaseInsensitive> HostsFileMap;
// A to hold a ref-counted map
struct RefCountedHostsFileMap : public RefCountObj {
  HostsFileMap hosts_file_map;
  ats_scoped_str HostFileText;
  ink_time_t next_sync_time; // time of the next sync
};

//
// HostDBCache (Private)
//
struct HostDBCache {
  int start(int flags = 0);
  // Map to contain all of the host file overrides, initialize it to empty
  Ptr<RefCountedHostsFileMap> hosts_file_ptr;
  // TODO: make ATS call a close() method or something on shutdown (it does nothing of the sort today)
  RefCountCache<HostDBInfo> *refcountcache;

  // TODO configurable number of items in the cache
  Queue<HostDBContinuation, Continuation::Link_link> *pending_dns;
  Queue<HostDBContinuation, Continuation::Link_link> &pending_dns_for_hash(const CryptoHash &hash);
  Queue<HostDBContinuation, Continuation::Link_link> *remoteHostDBQueue;
  HostDBCache();
  bool is_pending_dns_for_hash(const CryptoHash &hash);
};

inline int
HostDBRoundRobin::index_of(sockaddr const *ip)
{
  bool bad = (rrcount <= 0 || (unsigned int)rrcount > hostdb_round_robin_max_count || good <= 0 ||
              (unsigned int)good > hostdb_round_robin_max_count);
  if (bad) {
    ink_assert(!"bad round robin size");
    return -1;
  }

  for (int i = 0; i < good; i++) {
    if (ats_ip_addr_eq(ip, info(i).ip())) {
      return i;
    }
  }

  return -1;
}

inline HostDBInfo *
HostDBRoundRobin::find_ip(sockaddr const *ip)
{
  int idx = this->index_of(ip);
  return idx < 0 ? nullptr : &info(idx);
}

inline HostDBInfo *
HostDBRoundRobin::select_next(sockaddr const *ip)
{
  HostDBInfo *zret = nullptr;
  if (good > 1) {
    int idx = this->index_of(ip);
    if (idx >= 0) {
      idx  = (idx + 1) % good;
      zret = &info(idx);
    }
  }
  return zret;
}

inline HostDBInfo *
HostDBRoundRobin::find_target(const char *target)
{
  bool bad = (rrcount <= 0 || (unsigned int)rrcount > hostdb_round_robin_max_count || good <= 0 ||
              (unsigned int)good > hostdb_round_robin_max_count);
  if (bad) {
    ink_assert(!"bad round robin size");
    return nullptr;
  }

  uint32_t key = makeHostHash(target);
  for (int i = 0; i < good; i++) {
    if (info(i).data.srv.key == key && !strcmp(target, info(i).srvname(this)))
      return &info(i);
  }
  return nullptr;
}

inline HostDBInfo *
HostDBRoundRobin::select_best_http(sockaddr const *client_ip, ink_time_t now, int32_t fail_window)
{
  bool bad = (rrcount <= 0 || (unsigned int)rrcount > hostdb_round_robin_max_count || good <= 0 ||
              (unsigned int)good > hostdb_round_robin_max_count);

  if (bad) {
    ink_assert(!"bad round robin size");
    return nullptr;
  }

  int best_any = 0;
  int best_up  = -1;

  // Basic round robin, increment current and mod with how many we have
  if (HostDBProcessor::hostdb_strict_round_robin) {
    Debug("hostdb", "Using strict round robin");
    // Check that the host we selected is alive
    for (int i = 0; i < good; i++) {
      best_any = current++ % good;
      if (info(best_any).is_alive(now, fail_window)) {
        best_up = best_any;
        break;
      }
    }
  } else if (HostDBProcessor::hostdb_timed_round_robin > 0) {
    Debug("hostdb", "Using timed round-robin for HTTP");
    if ((now - timed_rr_ctime) > HostDBProcessor::hostdb_timed_round_robin) {
      Debug("hostdb", "Timed interval expired.. rotating");
      ++current;
      timed_rr_ctime = now;
    }
    for (int i = 0; i < good; i++) {
      best_any = (current + i) % good;
      if (info(best_any).is_alive(now, fail_window)) {
        best_up = best_any;
        break;
      }
    }
    Debug("hostdb", "Using %d for best_up", best_up);
  } else {
    Debug("hostdb", "Using default round robin");
    unsigned int best_hash_any = 0;
    unsigned int best_hash_up  = 0;
    sockaddr const *ip;
    for (int i = 0; i < good; i++) {
      ip             = info(i).ip();
      unsigned int h = HOSTDB_CLIENT_IP_HASH(client_ip, ip);
      if (best_hash_any <= h) {
        best_any      = i;
        best_hash_any = h;
      }
      if (info(i).is_alive(now, fail_window)) {
        if (best_hash_up <= h) {
          best_up      = i;
          best_hash_up = h;
        }
      }
    }
  }

  if (best_up != -1) {
    ink_assert(best_up >= 0 && best_up < good);
    return &info(best_up);
  } else {
    ink_assert(best_any >= 0 && best_any < good);
    return &info(best_any);
  }
}

inline HostDBInfo *
HostDBRoundRobin::select_best_srv(char *target, InkRand *rand, ink_time_t now, int32_t fail_window)
{
  bool bad = (rrcount <= 0 || (unsigned int)rrcount > hostdb_round_robin_max_count || good <= 0 ||
              (unsigned int)good > hostdb_round_robin_max_count);

  if (bad) {
    ink_assert(!"bad round robin size");
    return nullptr;
  }

#ifdef DEBUG
  for (int i = 1; i < good; ++i) {
    ink_assert(info(i).data.srv.srv_priority >= info(i - 1).data.srv.srv_priority);
  }
#endif

  int i           = 0;
  int len         = 0;
  uint32_t weight = 0, p = INT32_MAX;
  HostDBInfo *result = nullptr;
  HostDBInfo *infos[good];
  do {
    // if the real isn't alive-- exclude it from selection
    if (!info(i).is_alive(now, fail_window)) {
      continue;
    }

    if (info(i).data.srv.srv_priority <= p) {
      p = info(i).data.srv.srv_priority;
      weight += info(i).data.srv.srv_weight;
      infos[len++] = &info(i);
    } else
      break;
  } while (++i < good);

  if (len == 0) { // all failed
    result = &info(current++ % good);
  } else if (weight == 0) { // srv weight is 0
    result = &info(current++ % len);
  } else {
    uint32_t xx = rand->random() % weight;
    for (i = 0; i < len - 1 && xx >= infos[i]->data.srv.srv_weight; ++i)
      xx -= infos[i]->data.srv.srv_weight;

    result = infos[i];
  }

  if (result) {
    ink_strlcpy(target, result->srvname(this), MAXDNAME);
    return result;
  }
  return nullptr;
}

//
// Types
//

/** Container for a hash and its dependent data.
    This handles both the host name and raw address cases.
*/
struct HostDBHash {
  typedef HostDBHash self; ///< Self reference type.

  CryptoHash hash; ///< The hash value.

  const char *host_name; ///< Host name.
  int host_len;          ///< Length of @a _host_name
  IpAddr ip;             ///< IP address.
  in_port_t port;        ///< IP port (host order).
  /// DNS server. Not strictly part of the hash data but
  /// it's both used by @c HostDBContinuation and provides access to
  /// hash data. It's just handier to store it here for both uses.
  DNSServer *dns_server;
  SplitDNS *pSD;      ///< Hold the container for @a dns_server.
  HostDBMark db_mark; ///< Mark / type of record.

  /// Default constructor.
  HostDBHash();
  /// Destructor.
  ~HostDBHash();
  /// Recompute and update the hash.
  void refresh();
  /** Assign a hostname.
      This updates the split DNS data as well.
  */
  self &set_host(const char *name, int len);
};

//
// Handles a HostDB lookup request
//
struct HostDBContinuation;
typedef int (HostDBContinuation::*HostDBContHandler)(int, void *);

struct HostDBContinuation : public Continuation {
  Action action;
  HostDBHash hash;
  //  IpEndpoint ip;
  unsigned int ttl = 0;
  //  HostDBMark db_mark; ///< Target type.
  /// Original IP address family style. Note this will disagree with
  /// @a hash.db_mark when doing a retry on an alternate family. The retry
  /// logic depends on it to avoid looping.
  HostResStyle host_res_style = DEFAULT_OPTIONS.host_res_style; ///< Address family priority.
  int dns_lookup_timeout      = DEFAULT_OPTIONS.timeout;
  Event *timeout              = nullptr;
  Continuation *from_cont     = nullptr;
  HostDBApplicationInfo app;
  int probe_depth            = 0;
  size_t current_iterate_pos = 0;
  //  char name[MAXDNAME];
  //  int namelen;
  char hash_host_name_store[MAXDNAME + 1]; // used as backing store for @a hash
  char srv_target_name[MAXDNAME];
  //  void *m_pDS;
  Action *pending_action = nullptr;

  unsigned int missing : 1;
  unsigned int force_dns : 1;
  unsigned int round_robin : 1;

  int probeEvent(int event, Event *e);
  int iterateEvent(int event, Event *e);
  int dnsEvent(int event, HostEnt *e);
  int dnsPendingEvent(int event, Event *e);
  int backgroundEvent(int event, Event *e);
  int retryEvent(int event, Event *e);
  int removeEvent(int event, Event *e);
  int setbyEvent(int event, Event *e);

  /// Recompute the hash and update ancillary values.
  void refresh_hash();
  void do_dns();
  bool
  is_byname()
  {
    return hash.db_mark == HOSTDB_MARK_IPV4 || hash.db_mark == HOSTDB_MARK_IPV6;
  }
  bool
  is_srv()
  {
    return hash.db_mark == HOSTDB_MARK_SRV;
  }
  HostDBInfo *lookup_done(IpAddr const &ip, const char *aname, bool round_robin, unsigned int attl, SRVHosts *s = nullptr,
                          HostDBInfo *r = nullptr);
  int key_partition();
  void remove_trigger_pending_dns();
  int set_check_pending_dns();

  HostDBInfo *insert(unsigned int attl);

  /** Optional values for @c init.
   */
  struct Options {
    typedef Options self; ///< Self reference type.

    int timeout;                 ///< Timeout value. Default 0
    HostResStyle host_res_style; ///< IP address family fallback. Default @c HOST_RES_NONE
    bool force_dns;              ///< Force DNS lookup. Default @c false
    Continuation *cont;          ///< Continuation / action. Default @c nullptr (none)

    Options() : timeout(0), host_res_style(HOST_RES_NONE), force_dns(false), cont(nullptr) {}
  };
  static const Options DEFAULT_OPTIONS; ///< Default defaults.
  void init(HostDBHash const &hash, Options const &opt = DEFAULT_OPTIONS);
  int make_get_message(char *buf, int len);
  int make_put_message(HostDBInfo *r, Continuation *c, char *buf, int len);

  HostDBContinuation() : missing(false), force_dns(DEFAULT_OPTIONS.force_dns), round_robin(false)
  {
    ink_zero(hash_host_name_store);
    ink_zero(hash.hash);
    SET_HANDLER((HostDBContHandler)&HostDBContinuation::probeEvent);
  }
};

inline unsigned int
master_hash(CryptoHash const &hash)
{
  return static_cast<int>(hash[1] >> 32);
}

inline bool
is_dotted_form_hostname(const char *c)
{
  return -1 != (int)ink_inet_addr(c);
}

inline Queue<HostDBContinuation> &
HostDBCache::pending_dns_for_hash(const CryptoHash &hash)
{
  return pending_dns[this->refcountcache->partition_for_key(hash.fold())];
}

inline int
HostDBContinuation::key_partition()
{
  return hostDB.refcountcache->partition_for_key(hash.hash.fold());
}
