/*
  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.
*/
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Implement the classes for the various types of hash keys we support.
//
#pragma once

#include <string>
#include <memory>

#include "ts/ts.h"

#include "operator.h"
#include "resources.h"
#include "value.h"

// Forward declarations
class Parser;

// Full includes needed for member variables
#include "conditions.h"

///////////////////////////////////////////////////////////////////////////////
// Operator declarations.
//
class OperatorSetConfig : public Operator
{
public:
  OperatorSetConfig() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetConfig"); }

  // noncopyable
  OperatorSetConfig(const OperatorSetConfig &) = delete;
  void operator=(const OperatorSetConfig &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  TSOverridableConfigKey _key  = TS_CONFIG_NULL;
  TSRecordDataType       _type = TS_RECORDDATATYPE_NULL;

  std::string _config;
  Value       _value;
};

class OperatorSetStatus : public Operator
{
public:
  OperatorSetStatus() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetStatus"); }

  // noncopyable
  OperatorSetStatus(const OperatorSetStatus &) = delete;
  void operator=(const OperatorSetStatus &)    = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value       _status;
  const char *_reason     = nullptr;
  int         _reason_len = 0;
};

class OperatorSetStatusReason : public Operator
{
public:
  OperatorSetStatusReason() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetStatusReason"); }

  // noncopyable
  OperatorSetStatusReason(const OperatorSetStatusReason &) = delete;
  void operator=(const OperatorSetStatusReason &)          = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _reason;
};

class OperatorSetDestination : public Operator
{
public:
  OperatorSetDestination() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetDestination"); }

  // noncopyable
  OperatorSetDestination(const OperatorSetDestination &) = delete;
  void operator=(const OperatorSetDestination &)         = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  UrlQualifiers _url_qual = URL_QUAL_NONE;
  Value         _value;
};

// All the header operators share a base class
class OperatorRMDestination : public Operator
{
public:
  OperatorRMDestination() { Dbg(dbg_ctl, "Calling CTOR for OperatorRMDestination"); }

  // noncopyable
  OperatorRMDestination(const OperatorRMDestination &) = delete;
  void operator=(const OperatorRMDestination &)        = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  UrlQualifiers                 _url_qual = URL_QUAL_NONE;
  bool                          _keep     = false;
  std::string                   _stop     = "";
  std::vector<std::string_view> _stop_list;
};

class OperatorSetRedirect : public Operator
{
public:
  OperatorSetRedirect() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetRedirect"); }

  // noncopyable
  OperatorSetRedirect(const OperatorSetRedirect &) = delete;
  void operator=(const OperatorSetRedirect &)      = delete;

  void initialize(Parser &p) override;

  TSHttpStatus
  get_status() const
  {
    return static_cast<TSHttpStatus>(_status.get_int_value());
  }

  const std::string &
  get_location() const
  {
    return _location.get_value();
  }

protected:
  void initialize_hooks() override;

  bool exec(const Resources &res) const override;

private:
  Value _status;
  Value _location;
};

class OperatorNoOp : public Operator
{
public:
  OperatorNoOp() { Dbg(dbg_ctl, "Calling CTOR for OperatorNoOp"); }

  // noncopyable
  OperatorNoOp(const OperatorNoOp &)   = delete;
  void operator=(const OperatorNoOp &) = delete;

protected:
  bool
  exec(const Resources & /* res ATS_UNUSED */) const override
  {
    return true;
  };
};

class OperatorSetTimeoutOut : public Operator
{
public:
  OperatorSetTimeoutOut() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetTimeoutOut"); }

  // noncopyable
  OperatorSetTimeoutOut(const OperatorSetTimeoutOut &) = delete;
  void operator=(const OperatorSetTimeoutOut &)        = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  enum TimeoutOutType {
    TO_OUT_UNDEFINED,
    TO_OUT_ACTIVE,
    TO_OUT_INACTIVE,
    TO_OUT_CONNECT,
    TO_OUT_DNS,
  };

  TimeoutOutType _type = TO_OUT_UNDEFINED;
  Value          _timeout;
};

class OperatorSkipRemap : public Operator
{
public:
  OperatorSkipRemap() { Dbg(dbg_ctl, "Calling CTOR for OperatorSkipRemap"); }

  // noncopyable
  OperatorSkipRemap(const OperatorSkipRemap &) = delete;
  void operator=(const OperatorSkipRemap &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  bool _skip_remap = false;
};

// All the header operators share a base class
class OperatorRMHeader : public OperatorHeaders
{
public:
  OperatorRMHeader() { Dbg(dbg_ctl, "Calling CTOR for OperatorRMHeader"); }

  // noncopyable
  OperatorRMHeader(const OperatorRMHeader &) = delete;
  void operator=(const OperatorRMHeader &)   = delete;

protected:
  bool exec(const Resources &res) const override;
};

class OperatorAddHeader : public OperatorHeaders
{
public:
  OperatorAddHeader() { Dbg(dbg_ctl, "Calling CTOR for OperatorAddHeader"); }

  // noncopyable
  OperatorAddHeader(const OperatorAddHeader &) = delete;
  void operator=(const OperatorAddHeader &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

class OperatorSetHeader : public OperatorHeaders
{
public:
  OperatorSetHeader() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetHeader"); }

  // noncopyable
  OperatorSetHeader(const OperatorSetHeader &) = delete;
  void operator=(const OperatorSetHeader &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

class OperatorCounter : public Operator
{
public:
  OperatorCounter() { Dbg(dbg_ctl, "Calling CTOR for OperatorCounter"); }

  // noncopyable
  OperatorCounter(const OperatorCounter &) = delete;
  void operator=(const OperatorCounter &)  = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  std::string _counter_name;
  int         _counter = TS_ERROR;
};

class OperatorRMCookie : public OperatorCookies
{
public:
  OperatorRMCookie() { Dbg(dbg_ctl, "Calling CTOR for OperatorRMCookie"); }

  // noncopyable
  OperatorRMCookie(const OperatorRMCookie &) = delete;
  void operator=(const OperatorRMCookie &)   = delete;

protected:
  bool exec(const Resources &res) const override;
};

class OperatorAddCookie : public OperatorCookies
{
public:
  OperatorAddCookie() { Dbg(dbg_ctl, "Calling CTOR for OperatorAddCookie"); }

  // noncopyable
  OperatorAddCookie(const OperatorAddCookie &) = delete;
  void operator=(const OperatorAddCookie &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

class OperatorSetCookie : public OperatorCookies
{
public:
  OperatorSetCookie() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetCookie"); }

  // noncopyable
  OperatorSetCookie(const OperatorSetCookie &) = delete;
  void operator=(const OperatorSetCookie &)    = delete;

  void initialize(Parser &p) override;

protected:
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

namespace CookieHelper
{
enum CookieOp { COOKIE_OP_DEL, COOKIE_OP_ADD, COOKIE_OP_SET };

/*
 * This function returns if cookies need to be changed or not.
 * If the return value is true, updated_cookies would be cookies after the change.
 */
bool cookieModifyHelper(const char *cookies, const size_t cookies_len, std::string &updated_cookies, const CookieOp cookie_op,
                        const std::string &cookie_key, const std::string &cookie_value = std::string());
} // namespace CookieHelper

class OperatorSetConnDSCP : public Operator
{
public:
  OperatorSetConnDSCP() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetConnDSCP"); }

  // noncopyable
  OperatorSetConnDSCP(const OperatorSetConnDSCP &) = delete;
  void operator=(const OperatorSetConnDSCP &)      = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _ds_value;
};

class OperatorSetConnMark : public Operator
{
public:
  OperatorSetConnMark() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetConnMark"); }

  // noncopyable
  OperatorSetConnMark(const OperatorSetConnMark &) = delete;
  void operator=(const OperatorSetConnMark &)      = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _ds_value;
};

class OperatorSetDebug : public Operator
{
public:
  OperatorSetDebug() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetDebug"); }

  // noncopyable
  OperatorSetDebug(const OperatorSetDebug &) = delete;
  void operator=(const OperatorSetDebug &)   = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;
};

class OperatorSetBody : public Operator
{
public:
  OperatorSetBody() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetBody"); }

  // noncopyable
  OperatorSetBody(const OperatorSetBody &) = delete;
  void operator=(const OperatorSetBody &)  = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

class OperatorSetHttpCntl : public Operator
{
public:
  OperatorSetHttpCntl() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetHttpCntl"); }

  // noncopyable
  OperatorSetHttpCntl(const OperatorSetHttpCntl &) = delete;
  void operator=(const OperatorSetHttpCntl &)      = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  bool           _flag = false;
  TSHttpCntlType _cntl_qual;
};

class OperatorSetPluginCntl : public Operator
{
public:
  OperatorSetPluginCntl() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetPluginCntl"); }

  // noncopyable
  OperatorSetPluginCntl(const OperatorSetPluginCntl &) = delete;
  void operator=(const OperatorSetPluginCntl &)        = delete;

  void initialize(Parser &p) override;

  enum class PluginCtrl {
    TIMEZONE,
    INBOUND_IP_SOURCE,
  };

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

  bool
  need_txn_private_slot() const override
  {
    return true;
  }

private:
  PluginCtrl _name;
  int        _value;
};

class RemapPluginInst; // Opaque to the HRW operator, but needed in the implementation.

class OperatorRunPlugin : public Operator
{
public:
  OperatorRunPlugin() { Dbg(dbg_ctl, "Calling CTOR for OperatorRunPlugin"); }

  // This one is special, since we have to remove the old plugin from the factory.
  ~OperatorRunPlugin() override
  {
    Dbg(dbg_ctl, "Calling DTOR for OperatorRunPlugin");

    if (_plugin) {
      _plugin->done();
      _plugin = nullptr;
    }
  }

  // noncopyable
  OperatorRunPlugin(const OperatorRunPlugin &) = delete;
  void operator=(const OperatorRunPlugin &)    = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  RemapPluginInst *_plugin = nullptr;
};

class OperatorSetBodyFrom : public Operator
{
public:
  OperatorSetBodyFrom() { Dbg(pi_dbg_ctl, "Calling CTOR for OperatorSetBodyFrom"); }

  // noncopyable
  OperatorSetBodyFrom(const OperatorSetBodyFrom &) = delete;
  void operator=(const OperatorSetBodyFrom &)      = delete;

  void initialize(Parser &p) override;

  enum { TS_EVENT_FETCHSM_SUCCESS = 70000, TS_EVENT_FETCHSM_FAILURE = 70001, TS_EVENT_FETCHSM_TIMEOUT = 70002 };

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

class OperatorSetStateFlag : public Operator
{
public:
  OperatorSetStateFlag()
  {
    static_assert(sizeof(void *) == 8, "State Variables requires a 64-bit system.");
    Dbg(dbg_ctl, "Calling CTOR for OperatorSetStateFlag");
  }

  // noncopyable
  OperatorSetStateFlag(const OperatorSetStateFlag &) = delete;
  void operator=(const OperatorSetStateFlag &)       = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

  bool
  need_txn_slot() const override
  {
    return true;
  }

private:
  int      _flag_ix = -1;
  int      _flag    = false;
  uint64_t _mask    = 0;
};

class OperatorSetStateInt8 : public Operator
{
public:
  OperatorSetStateInt8()
  {
    static_assert(sizeof(void *) == 8, "State Variables requires a 64-bit system.");
    Dbg(dbg_ctl, "Calling CTOR for OperatorSetStateInt8");
  }

  // noncopyable
  OperatorSetStateInt8(const OperatorSetStateInt8 &) = delete;
  void operator=(const OperatorSetStateInt8 &)       = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

  bool
  need_txn_slot() const override
  {
    return true;
  }

private:
  int   _byte_ix = -1;
  Value _value;
};

class OperatorSetStateInt16 : public Operator
{
public:
  OperatorSetStateInt16()
  {
    static_assert(sizeof(void *) == 8, "State Variables requires a 64-bit system.");
    Dbg(dbg_ctl, "Calling CTOR for OperatorSetStateInt16");
  }

  // noncopyable
  OperatorSetStateInt16(const OperatorSetStateInt16 &) = delete;
  void operator=(const OperatorSetStateInt16 &)        = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

  bool
  need_txn_slot() const override
  {
    return true;
  }

private:
  Value _value;
};

class OperatorSetEffectiveAddress : public Operator
{
public:
  OperatorSetEffectiveAddress() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetEffectiveAddress"); }

  // noncopyable
  OperatorSetEffectiveAddress(const OperatorSetEffectiveAddress &) = delete;
  void operator=(const OperatorSetEffectiveAddress &)              = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

  bool
  need_txn_private_slot() const override
  {
    return true;
  }

private:
  Value _value;
};

class OperatorSetNextHopStrategy : public Operator
{
public:
  OperatorSetNextHopStrategy() { Dbg(dbg_ctl, "Calling CTOR for OperatorSetNextHopStrategy"); }

  // noncopyable
  OperatorSetNextHopStrategy(const OperatorSetNextHopStrategy &) = delete;
  void operator=(const OperatorSetNextHopStrategy &)             = delete;

  void initialize(Parser &p) override;

protected:
  void initialize_hooks() override;
  bool exec(const Resources &res) const override;

private:
  Value _value;
};

///////////////////////////////////////////////////////////////////////////////
// OperatorIf class - implements nested if/elif/else as a pseudo-operator.
// Keep this at the end of the files, since this is not really an Operator.
//
class OperatorIf : public Operator
{
public:
  struct CondOpSection {
    CondOpSection() = default;

    ~CondOpSection() = default;

    CondOpSection(const CondOpSection &)            = delete;
    CondOpSection &operator=(const CondOpSection &) = delete;

    bool
    has_operator() const
    {
      return ops.oper != nullptr;
    }

    ConditionGroup                 group;
    OperatorAndMods                ops;
    std::unique_ptr<CondOpSection> next; // For elif/else sections
  };

  OperatorIf() { Dbg(dbg_ctl, "Calling CTOR for OperatorIf"); }

  // noncopyable
  OperatorIf(const OperatorIf &)     = delete;
  void operator=(const OperatorIf &) = delete;

  ConditionGroup *new_section(Parser::CondClause clause);
  bool            add_operator(Parser &p, const char *filename, int lineno);
  Condition      *make_condition(Parser &p, const char *filename, int lineno);
  bool            has_operator() const;

  ConditionGroup *
  get_group()
  {
    return &_cur_section->group;
  }

  Parser::CondClause
  get_clause() const
  {
    return _clause;
  }

  CondOpSection *
  cur_section() const
  {
    return _cur_section;
  }

  OperModifiers exec_and_return_mods(const Resources &res) const;

protected:
  bool
  exec(const Resources &res) const override
  {
    OperModifiers mods = exec_and_return_mods(res);
    return !(mods & OPER_NO_REENABLE);
  }

private:
  OperModifiers exec_section(const CondOpSection *section, const Resources &res) const;

  CondOpSection      _sections;
  CondOpSection     *_cur_section = &_sections;
  Parser::CondClause _clause      = Parser::CondClause::COND;
};
