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

/*****************************************************************************
 *
 *  HostStatus.h - Interface to Host Status System
 *
 *
 ****************************************************************************/

#pragma once

#include <ctime>
#include <string>
#include <sstream>
#include "tscore/Filenames.h"
#include "tscore/Layout.h"
#include "tscore/ink_rwlock.h"
#include "records/RecProcess.h"

#include <unordered_map>

// host_status stats prefix.
static const std::string stat_prefix = "proxy.process.host_status.";

static const constexpr char *HostStatusNames[3] = {"HOST_STATUS_INIT", "HOST_STATUS_DOWN", "HOST_STATUS_UP"};
static const constexpr char *ReasonStatus[2]    = {"UP", "DOWN"};

struct Reason {
  static constexpr const unsigned int ACTIVE      = 0x1;
  static constexpr const unsigned int LOCAL       = 0x2;
  static constexpr const unsigned int MANUAL      = 0x4;
  static constexpr const unsigned int SELF_DETECT = 0x8;
  static constexpr const unsigned int ALL         = 0xf;

  static constexpr const char *ACTIVE_REASON      = "active";
  static constexpr const char *LOCAL_REASON       = "local";
  static constexpr const char *MANUAL_REASON      = "manual";
  static constexpr const char *SELF_DETECT_REASON = "self_detect";
  static constexpr const char *ALL_REASON         = "all";

  static constexpr const char *reasons[3] = {ACTIVE_REASON, LOCAL_REASON, MANUAL_REASON};

  static bool
  validReason(const char *reason)
  {
    for (const char *i : reasons) {
      if (strcmp(i, reason) == 0) {
        return true;
      }
    }
    return false;
  }

  static unsigned int
  getReason(const char *reason_str)
  {
    if (strcmp(reason_str, ACTIVE_REASON) == 0) {
      return ACTIVE;
    } else if (strcmp(reason_str, LOCAL_REASON) == 0) {
      return LOCAL;
    } else if (strcmp(reason_str, MANUAL_REASON) == 0) {
      return MANUAL;
    } else if (strcmp(reason_str, SELF_DETECT_REASON) == 0) {
      return SELF_DETECT;
    } else if (strcmp(reason_str, ALL_REASON) == 0) {
      return ALL;
    }
    // default is MANUAL
    return MANUAL;
  }
};

struct HostStatuses {
  std::string hostname;
  std::string status;
};

// host status POD
struct HostStatRec {
  TSHostStatus status;
  unsigned int reasons;
  // time the host was marked down for a given reason.
  time_t active_marked_down;
  time_t local_marked_down;
  time_t manual_marked_down;
  time_t self_detect_marked_down;
  // number of seconds that the host should be marked down for a given reason.
  unsigned int active_down_time;
  unsigned int local_down_time;
  unsigned int manual_down_time;

  HostStatRec();
  HostStatRec(std::string str);
  HostStatRec(const HostStatRec &src)
  {
    status                  = src.status;
    reasons                 = src.reasons;
    active_marked_down      = src.active_marked_down;
    active_down_time        = src.active_down_time;
    local_marked_down       = src.local_marked_down;
    local_down_time         = src.local_down_time;
    manual_marked_down      = src.manual_marked_down;
    manual_down_time        = src.manual_down_time;
    self_detect_marked_down = src.self_detect_marked_down;
  }
  ~HostStatRec() {}

  HostStatRec &operator=(const HostStatRec &source) = default;

  // serialize this HostStatusRec
  std::stringstream &
  operator<<(std::stringstream &os)
  {
    unsigned int r = getReasonState(Reason::ACTIVE);
    os << HostStatusNames[status];
    os << ",ACTIVE:" << ReasonStatus[r] << ":" << active_marked_down << ":" << active_down_time;
    r = getReasonState(Reason::LOCAL);
    os << ",LOCAL:" << ReasonStatus[r] << ":" << local_marked_down << ":" << local_down_time;
    r = getReasonState(Reason::MANUAL);
    os << ",MANUAL:" << ReasonStatus[r] << ":" << manual_marked_down << ":" << manual_down_time;
    r = getReasonState(Reason::SELF_DETECT);
    os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << self_detect_marked_down;

    return os;
  }

  // serialize a HostStatRec
  friend std::stringstream &
  operator<<(std::stringstream &os, HostStatRec &hs)
  {
    unsigned int r = hs.getReasonState(Reason::ACTIVE);
    os << HostStatusNames[hs.status];
    os << ",ACTIVE:" << ReasonStatus[r] << ":" << hs.active_marked_down << ":" << hs.active_down_time;
    r = hs.getReasonState(Reason::LOCAL);
    os << ",LOCAL:" << ReasonStatus[r] << ":" << hs.local_marked_down << ":" << hs.local_down_time;
    r = hs.getReasonState(Reason::MANUAL);
    os << ",MANUAL:" << ReasonStatus[r] << ":" << hs.manual_marked_down << ":" << hs.manual_down_time;
    r = hs.getReasonState(Reason::SELF_DETECT);
    os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << hs.self_detect_marked_down;

    return os;
  }

  inline unsigned int
  getReasonState(unsigned int reason)
  {
    unsigned int r = 0;
    if (reasons == 0) {
      r = 0;
    } else if (reasons & reason) {
      r = 1;
    }
    return r;
  }
};

class HostStatusSync : public Continuation
{
private:
  HostStatusSync()
  {
    getHostStatusPersistentFilePath();

    SET_HANDLER(&HostStatusSync::mainEvent);
  }

  ~HostStatusSync() = default;

public:
  HostStatusSync(HostStatusSync const &) = delete;

  std::string hostRecordsFile;

  static HostStatusSync *
  new_instance()
  {
    return new HostStatusSync;
  }

  void sync_task();
  void
  getHostStatusPersistentFilePath()
  {
    std::string rundir(RecConfigReadRuntimeDir());
    hostRecordsFile = Layout::relative_to(rundir, ts::filename::HOST_RECORDS);
  }

  // Deletes instance.
  int
  mainEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
  {
    sync_task();

    delete this;

    return EVENT_DONE;
  }
};

/**
 * Singleton placeholder for next hop status.
 */
struct HostStatus {
  ~HostStatus();

  static HostStatus &
  instance()
  {
    static HostStatus instance;
    return instance;
  }
  void         setHostStatus(const std::string_view name, const TSHostStatus status, const unsigned int down_time,
                             const unsigned int reason);
  void         loadFromPersistentStore();
  void         loadRecord(std::string_view name, HostStatRec &h);
  HostStatRec *getHostStatus(const std::string_view name);
  void         getAllHostStatuses(std::vector<HostStatuses> &hosts);
  std::string
  getHostStatusPersistentFilePath()
  {
    std::string rundir(RecConfigReadRuntimeDir());
    return Layout::relative_to(rundir, ts::filename::HOST_RECORDS);
  }

private:
  HostStatus();
  HostStatus(const HostStatus &obj)         = delete;
  HostStatus &operator=(HostStatus const &) = delete;

  // next hop status, key is hostname or ip string, data is HostStatRec
  std::unordered_map<std::string, HostStatRec *> hosts_statuses;

  ink_rwlock host_status_rwlock;
};
