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

/*****************************************************************************
 *
 *  ControlBase.cc - Base class to process generic modifiers to
 *                         ControlMatcher Directives
 *
 *
 ****************************************************************************/
#include "swoc/MemSpan.h"

#include "tscore/ink_platform.h"
#include "tscore/ink_defs.h"
#include "tscore/ink_time.h"

#include "tsutil/StringCompare.h"

#include "proxy/hdrs/URL.h"
#include "tscore/Tokenizer.h"
#include "proxy/ControlBase.h"
#include "tscore/MatcherUtils.h"
#include "proxy/hdrs/HTTP.h"
#include "proxy/ControlMatcher.h"
#include "proxy/hdrs/HdrUtils.h"

#include "swoc/string_view_util.h"

#include <string_view>
#include <utility>
#include <vector>

/** Used for printing IP address.
    @code
    uint32_t addr; // IP address.
    printf("IP address = " TS_IP_PRINTF_CODE,TS_IP_OCTETS(addr));
    @endcode
    @internal Need to move these to a common header.
 */
#define TS_IP_OCTETS(x)                                                                               \
  reinterpret_cast<unsigned const char *>(&(x))[0], reinterpret_cast<unsigned char const *>(&(x))[1], \
    reinterpret_cast<unsigned const char *>(&(x))[2], reinterpret_cast<unsigned char const *>(&(x))[3]

// ----------
ControlBase::Modifier::~Modifier() = default;
ControlBase::Modifier::Type
ControlBase::Modifier::type() const
{
  return Type::INVALID;
}
// --------------------------
namespace
{
// ----------
struct TimeMod : public ControlBase::Modifier {
  time_t start_time;
  time_t end_time;

  static const char *const NAME;

  Type                            type() const override;
  const char                     *name() const override;
  bool                            check(HttpRequestData *req) const override;
  void                            print(FILE *f) const override;
  static std::unique_ptr<TimeMod> make(char *value, const char **error);
  static const char              *timeOfDayToSeconds(const char *time_str, time_t *seconds);
};

const char *const TimeMod::NAME = "Time";
ControlBase::Modifier::Type
TimeMod::type() const
{
  return Type::TIME;
}
const char *
TimeMod::name() const
{
  return NAME;
}

void
TimeMod::print(FILE *f) const
{
  fprintf(f, "%s=%ld-%ld  ",
          // Have to cast because time_t can be 32 or 64 bits and the compiler
          // will barf if format code doesn't match.
          this->name(), static_cast<long>(start_time), static_cast<long>(end_time));
}
bool
TimeMod::check(HttpRequestData *req) const
{
  struct tm cur_time;
  time_t    timeOfDay = req->xact_start;
  // Use this to account for daylight savings time.
  ink_localtime_r(&timeOfDay, &cur_time);
  timeOfDay = cur_time.tm_hour * (60 * 60) + cur_time.tm_min * 60 + cur_time.tm_sec;
  return start_time <= timeOfDay && timeOfDay <= end_time;
}

std::unique_ptr<TimeMod>
TimeMod::make(char *value, const char **error)
{
  Tokenizer                rangeTok("-");
  std::unique_ptr<TimeMod> mod = nullptr;
  TimeMod                  tmp;
  int                      num_tok;

  num_tok = rangeTok.Initialize(value, SHARE_TOKS);
  if (num_tok == 1) {
    *error = "End time not specified";
  } else if (num_tok > 2) {
    *error = "Malformed time range";
  } else if (nullptr == (*error = timeOfDayToSeconds(rangeTok[0], &tmp.start_time)) &&
             nullptr == (*error = timeOfDayToSeconds(rangeTok[1], &tmp.end_time))) {
    mod = std::make_unique<TimeMod>(std::move(tmp));
  }
  return mod;
}
/**   Converts TimeOfDay (TOD) to second value.
      @a *seconds is set to number of seconds since midnight
      represented by @a time_str.

      @return 0 on success, static error string on failure.
*/
const char *
TimeMod::timeOfDayToSeconds(const char *time_str, time_t *seconds)
{
  int    hour = 0;
  int    min  = 0;
  int    sec  = 0;
  time_t tmp  = 0;

  // coverity[secure_coding]
  if (sscanf(time_str, "%d:%d:%d", &hour, &min, &sec) != 3) {
    // coverity[secure_coding]
    if (sscanf(time_str, "%d:%d", &hour, &min) != 2) {
      return "Malformed time specified";
    }
  }

  if (!(hour >= 0 && hour <= 23)) {
    return "Illegal hour specification";
  }
  tmp = hour * 60;

  if (!(min >= 0 && min <= 59)) {
    return "Illegal minute specification";
  }
  tmp = (tmp + min) * 60;

  if (!(sec >= 0 && sec <= 59)) {
    return "Illegal second specification";
  }
  tmp += sec;

  *seconds = tmp;
  return nullptr;
}

// ----------
struct PortMod : public ControlBase::Modifier {
  int start_port;
  int end_port;

  static const char *const NAME;

  const char *name() const override;
  bool        check(HttpRequestData *req) const override;
  void        print(FILE *f) const override;

  static std::unique_ptr<PortMod> make(char *value, const char **error);
};

const char *const PortMod::NAME = "Port";
const char *
PortMod::name() const
{
  return NAME;
}

void
PortMod::print(FILE *f) const
{
  fprintf(f, "%s=%d-%d  ", this->name(), start_port, end_port);
}

bool
PortMod::check(HttpRequestData *req) const
{
  int port = req->hdr->port_get();
  return start_port <= port && port <= end_port;
}

std::unique_ptr<PortMod>
PortMod::make(char *value, const char **error)
{
  Tokenizer rangeTok("-");
  PortMod   tmp;
  int       num_tok = rangeTok.Initialize(value, SHARE_TOKS);

  *error = nullptr;
  if (num_tok > 2) {
    *error = "Malformed Range";
    // coverity[secure_coding]
  } else if (sscanf(rangeTok[0], "%d", &tmp.start_port) != 1) {
    *error = "Invalid start port";
  } else if (num_tok == 2) {
    // coverity[secure_coding]
    if (sscanf(rangeTok[1], "%d", &tmp.end_port) != 1) {
      *error = "Invalid end port";
    } else if (tmp.end_port < tmp.start_port) {
      *error = "Malformed Range: end port < start port";
    }
  } else {
    tmp.end_port = tmp.start_port;
  }

  // If there's an error message, return null.
  // Otherwise create a new item and return it.
  return *error ? nullptr : std::make_unique<PortMod>(tmp);
}

// ----------
struct IPortMod : public ControlBase::Modifier {
  int _port;

  static const char *const NAME;

  IPortMod(int port);

  const char                      *name() const override;
  bool                             check(HttpRequestData *req) const override;
  void                             print(FILE *f) const override;
  static std::unique_ptr<IPortMod> make(char *value, const char **error);
};

const char *const IPortMod::NAME = "IPort";
IPortMod::IPortMod(int port) : _port(port) {}
const char *
IPortMod::name() const
{
  return NAME;
}

void
IPortMod::print(FILE *f) const
{
  fprintf(f, "%s=%d  ", this->name(), _port);
}
bool
IPortMod::check(HttpRequestData *req) const
{
  return req->incoming_port == _port;
}

std::unique_ptr<IPortMod>
IPortMod::make(char *value, const char **error)
{
  std::unique_ptr<IPortMod> zret = nullptr;
  int                       port;
  // coverity[secure_coding]
  if (sscanf(value, "%u", &port) == 1) {
    zret = std::make_unique<IPortMod>(port);
  } else {
    *error = "Invalid incoming port";
  }
  return zret;
}
// ----------
struct SrcIPMod : public ControlBase::Modifier {
  // Stored in host order because that's how they are compared.
  IpEndpoint start_addr; ///< Start address in HOST order.
  IpEndpoint end_addr;   ///< End address in HOST order.

  static const char *const NAME;

  Type                             type() const override;
  const char                      *name() const override;
  bool                             check(HttpRequestData *req) const override;
  void                             print(FILE *f) const override;
  static std::unique_ptr<SrcIPMod> make(char *value, const char **error);
};

const char *const SrcIPMod::NAME = "SrcIP";
ControlBase::Modifier::Type
SrcIPMod::type() const
{
  return Type::SRC_IP;
}
const char *
SrcIPMod::name() const
{
  return NAME;
}

void
SrcIPMod::print(FILE *f) const
{
  ip_text_buffer b1, b2;
  fprintf(f, "%s=%s-%s  ", this->name(), ats_ip_ntop(&start_addr.sa, b1, sizeof(b1)), ats_ip_ntop(&end_addr.sa, b2, sizeof(b2)));
}
bool
SrcIPMod::check(HttpRequestData *req) const
{
  // Compare in host order
  return ats_ip_addr_cmp(&start_addr, &req->src_ip) <= 0 && ats_ip_addr_cmp(&req->src_ip, &end_addr) <= 0;
}
std::unique_ptr<SrcIPMod>
SrcIPMod::make(char *value, const char **error)
{
  SrcIPMod                  tmp;
  std::unique_ptr<SrcIPMod> zret = nullptr;
  *error                         = ExtractIpRange(value, &tmp.start_addr.sa, &tmp.end_addr.sa);

  if (!*error) {
    zret = std::make_unique<SrcIPMod>(tmp);
  }
  return zret;
}
// ----------
struct SchemeMod : public ControlBase::Modifier {
  int _scheme; ///< Tokenized scheme.

  static const char *const NAME;

  SchemeMod(int scheme);

  Type        type() const override;
  const char *name() const override;
  bool        check(HttpRequestData *req) const override;
  void        print(FILE *f) const override;

  const char *getWksText() const;

  static std::unique_ptr<SchemeMod> make(char *value, const char **error);
};

const char *const SchemeMod::NAME = "Scheme";

SchemeMod::SchemeMod(int scheme) : _scheme(scheme) {}

ControlBase::Modifier::Type
SchemeMod::type() const
{
  return Type::SCHEME;
}
const char *
SchemeMod::name() const
{
  return NAME;
}
const char *
SchemeMod::getWksText() const
{
  return hdrtoken_index_to_wks(_scheme);
}

bool
SchemeMod::check(HttpRequestData *req) const
{
  return req->hdr->url_get()->scheme_get_wksidx() == _scheme;
}
void
SchemeMod::print(FILE *f) const
{
  fprintf(f, "%s=%s  ", this->name(), hdrtoken_index_to_wks(_scheme));
}
std::unique_ptr<SchemeMod>
SchemeMod::make(char *value, const char **error)
{
  std::unique_ptr<SchemeMod> zret   = nullptr;
  int                        scheme = hdrtoken_tokenize(value, strlen(value));
  if (scheme < 0) {
    *error = "Unknown scheme";
  } else {
    zret = std::make_unique<SchemeMod>(scheme);
  }
  return zret;
}

// ----------
// This is a base class for all of the mods that have a
// text string.
struct TextMod : public ControlBase::Modifier {
  swoc::MemSpan<char> text;

  TextMod();
  ~TextMod() override;

  // Calls name() which the subclass must provide.
  void print(FILE *f) const override;

  // Copy the given NUL-terminated string to the text buffer.
  void set(const char *value);
};

TextMod::TextMod() : text() {}
TextMod::~TextMod()
{
  free(text.data());
}

void
TextMod::print(FILE *f) const
{
  fprintf(f, "%s=%.*s  ", this->name(), static_cast<int>(text.size()), text.data());
}

void
TextMod::set(const char *value)
{
  free(this->text.data());
  this->text.assign(ats_strdup(value), strlen(value));
}

struct MultiTextMod : public ControlBase::Modifier {
  std::string                 _s; ///< Storage for all strings.
  std::vector<swoc::TextView> text_vec;
  MultiTextMod();
  ~MultiTextMod() override = default;

  // Copy the value to the MultiTextMod buffer.
  void set(char *value);

  // Calls name() which the subclass must provide.
  void print(FILE *f) const override;
};

MultiTextMod::MultiTextMod() = default;

void
MultiTextMod::print(FILE *f) const
{
  for (auto text_iter : this->text_vec) {
    fprintf(f, "%s=%.*s ", this->name(), static_cast<int>(text_iter.size()), text_iter.data());
  }
}

void
MultiTextMod::set(char *value)
{
  _s.assign(value); // local copy.
  swoc::TextView src(_s);
  while (src.ltrim(',')) { // don't allow empty tokens.
    auto token = src.take_prefix_at(',');
    this->text_vec.push_back(token);
  }
}

// ----------
struct MethodMod : public TextMod {
  static const char *const NAME;

  Type        type() const override;
  const char *name() const override;
  bool        check(HttpRequestData *req) const override;

  static std::unique_ptr<MethodMod> make(char *value, const char **error);
};
const char *const MethodMod::NAME = "Method";
ControlBase::Modifier::Type
MethodMod::type() const
{
  return Type::METHOD;
}
const char *
MethodMod::name() const
{
  return NAME;
}
bool
MethodMod::check(HttpRequestData *req) const
{
  auto method{req->hdr->method_get()};
  return method.length() == text.length() && 0 == strcasecmp(method, std::string_view(text.data(), text.length()));
}
std::unique_ptr<MethodMod>
MethodMod::make(char *value, const char **)
{
  auto mod = std::make_unique<MethodMod>();
  mod->set(value);
  return mod;
}

// ----------
struct PrefixMod : public TextMod {
  static const char *const NAME;

  Type                              type() const override;
  const char                       *name() const override;
  bool                              check(HttpRequestData *req) const override;
  static std::unique_ptr<PrefixMod> make(char *value, const char **error);
};

const char *const PrefixMod::NAME = "Prefix";
ControlBase::Modifier::Type
PrefixMod::type() const
{
  return Type::PREFIX;
}
const char *
PrefixMod::name() const
{
  return NAME;
}
bool
PrefixMod::check(HttpRequestData *req) const
{
  auto path{req->hdr->url_get()->path_get()};
  bool zret = path.length() >= text.size() && 0 == memcmp(path.data(), text.data(), text.size());
  /*
    Dbg(dbg_ctl_cache_control, "Prefix check: URL=%0.*s Mod=%0.*s Z=%s",
        path_len, path, text.size(), text.data(),
        zret ? "Match" : "Fail"
    );
  */
  return zret;
}
std::unique_ptr<PrefixMod>
PrefixMod::make(char *value, const char ** /* error ATS_UNUSED */)
{
  auto mod = std::make_unique<PrefixMod>();
  // strip leading slashes because get_path which is used later
  // doesn't include them from the URL.
  while ('/' == *value) {
    ++value;
  }
  mod->set(value);
  return mod;
}

// ----------
struct SuffixMod : public MultiTextMod {
  static const char *const NAME;

  Type                              type() const override;
  const char                       *name() const override;
  bool                              check(HttpRequestData *req) const override;
  static std::unique_ptr<SuffixMod> make(char *value, const char **error);
};
const char *const SuffixMod::NAME = "Suffix";
ControlBase::Modifier::Type
SuffixMod::type() const
{
  return Type::SUFFIX;
}
const char *
SuffixMod::name() const
{
  return NAME;
}
bool
SuffixMod::check(HttpRequestData *req) const
{
  auto path{req->hdr->url_get()->path_get()};

  if (1 == this->text_vec.size() && 1 == this->text_vec[0].size() && this->text_vec[0][0] == '*') {
    return true;
  }

  for (auto text_iter : this->text_vec) {
    if (path.length() >= text_iter.size() &&
        0 == strncasecmp(path.data() + path.length() - text_iter.size(), text_iter.data(), text_iter.size())) {
      return true;
    }
  }

  return false;
}
std::unique_ptr<SuffixMod>
SuffixMod::make(char *value, const char ** /* error ATS_UNUSED */)
{
  auto mod = std::make_unique<SuffixMod>();
  mod->set(value);
  return mod;
}

// ----------
struct TagMod : public TextMod {
  static const char *const NAME;

  Type                           type() const override;
  const char                    *name() const override;
  bool                           check(HttpRequestData *req) const override;
  static std::unique_ptr<TagMod> make(char *value, const char **error);
};
const char *const TagMod::NAME = "Tag";
ControlBase::Modifier::Type
TagMod::type() const
{
  return Type::TAG;
}
const char *
TagMod::name() const
{
  return NAME;
}
bool
TagMod::check(HttpRequestData *req) const
{
  return 0 == strcmp(req->tag, text.data());
}
std::unique_ptr<TagMod>
TagMod::make(char *value, const char ** /* error ATS_UNUSED */)
{
  auto mod = std::make_unique<TagMod>();
  mod->set(value);
  return mod;
}

// ----------
struct InternalMod : public ControlBase::Modifier {
  bool                     flag;
  static const char *const NAME;

  Type
  type() const override
  {
    return Type::INTERNAL;
  }
  const char *
  name() const override
  {
    return NAME;
  }
  bool
  check(HttpRequestData *req) const override
  {
    return req->internal_txn == flag;
  }
  void
  print(FILE *f) const override
  {
    fprintf(f, "%s=%s  ", this->name(), flag ? "true" : "false");
  }
  static std::unique_ptr<InternalMod> make(char *value, const char **error);
};

const char *const InternalMod::NAME = "Internal";

std::unique_ptr<InternalMod>
InternalMod::make(char *value, const char **error)
{
  InternalMod tmp;

  if (ts::iequals("false", value)) {
    tmp.flag = false;
  } else if (ts::iequals("true", value)) {
    tmp.flag = true;
  } else {
    *error = "Value must be true or false";
  }

  if (*error) {
    return nullptr;
  } else {
    return std::make_unique<InternalMod>(tmp);
  }
}

// ----------
} // namespace
// ------------------------------------------------
ControlBase::~ControlBase()
{
  this->clear();
}

void
ControlBase::clear()
{
  _mods.clear();
}

void
ControlBase::Print() const
{
  int n = _mods.size();

  if (0 >= n) {
    return;
  }

  printf("\t\t\t");
  for (intptr_t i = 0; i < n; ++i) {
    Modifier *cur_mod = _mods[i].get();
    if (!cur_mod) {
      printf("INVALID  ");
    } else {
      cur_mod->print(stdout);
    }
  }
  printf("\n");
}

const char *
ControlBase::getSchemeModText() const
{
  Modifier *mod = this->findModOfType(Modifier::Type::SCHEME);

  if (mod) {
    return static_cast<SchemeMod *>(mod)->getWksText();
  }

  return nullptr;
}

bool
ControlBase::CheckModifiers(HttpRequestData *request_data)
{
  if (!request_data->hdr) {
    // we use the same request_data for Socks as well (only IpMatcher)
    // we just return false here
    return true;
  }

  // If the incoming request has no tag but the entry does, or both
  // have tags that do not match, then we do NOT have a match.
  if (!request_data->tag && findModOfType(Modifier::Type::TAG)) {
    return false;
  }

  for (auto &cur_mod : _mods) {
    if (cur_mod && !cur_mod->check(request_data)) {
      return false;
    }
  }

  return true;
}

enum class mod_errors {
  UNKNOWN,
  PARSE_FAILED,
  BAD_MOD,
  CALLEE_GENERATED,
};

static const char *errorFormats[] = {
  "Unknown error parsing modifier",
  "Unable to parse modifier",
  "Unknown modifier",
  "Callee Generated",
};

ControlBase::Modifier *
ControlBase::findModOfType(Modifier::Type t) const
{
  for (auto &m : _mods) {
    if (m && t == m->type()) {
      return m.get();
    }
  }

  return nullptr;
}

const char *
ControlBase::ProcessModifiers(matcher_line *line_info)
{
  // Variables for error processing
  const char *errBuf = nullptr;
  mod_errors  err    = mod_errors::UNKNOWN;

  int n_elts = line_info->num_el; // Element count for line.

  // No elements -> no modifiers.
  if (0 >= n_elts) {
    return nullptr;
  }
  // Can't have more modifiers than elements, so reasonable upper bound.
  _mods.clear();
  _mods.reserve(n_elts);

  // As elements are consumed, the labels are nulled out and the element
  // count decremented. So we have to scan the entire array to be sure of
  // finding all the elements. We'll track the element count so we can
  // escape if we've found all of the elements.
  for (int i = 0; n_elts && mod_errors::UNKNOWN == err && i < MATCHER_MAX_TOKENS; ++i) {
    char *label = line_info->line[0][i];
    char *value = line_info->line[1][i];

    if (!label) {
      continue; // Already use.
    }
    if (!value) {
      err = mod_errors::PARSE_FAILED;
      break;
    }

    std::unique_ptr<Modifier> mod = nullptr;
    if (strcasecmp(label, "port") == 0) {
      mod = PortMod::make(value, &errBuf);
    } else if (strcasecmp(label, "iport") == 0) {
      mod = IPortMod::make(value, &errBuf);
    } else if (strcasecmp(label, "scheme") == 0) {
      mod = SchemeMod::make(value, &errBuf);
    } else if (strcasecmp(label, "method") == 0) {
      mod = MethodMod::make(value, &errBuf);
    } else if (strcasecmp(label, "prefix") == 0) {
      mod = PrefixMod::make(value, &errBuf);
    } else if (strcasecmp(label, "suffix") == 0) {
      mod = SuffixMod::make(value, &errBuf);
    } else if (strcasecmp(label, "src_ip") == 0) {
      mod = SrcIPMod::make(value, &errBuf);
    } else if (strcasecmp(label, "time") == 0) {
      mod = TimeMod::make(value, &errBuf);
    } else if (strcasecmp(label, "tag") == 0) {
      mod = TagMod::make(value, &errBuf);
    } else if (strcasecmp(label, "internal") == 0) {
      mod = InternalMod::make(value, &errBuf);
    } else {
      err = mod_errors::BAD_MOD;
    }

    if (errBuf) {
      err = mod_errors::CALLEE_GENERATED; // Mod make failed.
    }

    // If nothing went wrong, add the mod and bump the element count.
    if (mod_errors::UNKNOWN == err) {
      _mods.push_back(std::move(mod));
      --n_elts;
    }
  }

  if (err != mod_errors::UNKNOWN) {
    this->clear();
    if (err != mod_errors::CALLEE_GENERATED) {
      errBuf = errorFormats[static_cast<int>(err)];
    }
  }

  return errBuf;
}
