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

#include "ts/ts.h"
#include "ts/remap.h"
#include "tscore/ink_defs.h"

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <string>

static const char PLUGIN_NAME[] = "conf_remap";

// This makes the plugin depend on the version of traffic server installed, but that's
// OK, since this plugin is distributed only with the "core" (it's a core piece).
#define MAX_OVERRIDABLE_CONFIGS TS_CONFIG_LAST_ENTRY

// Class to hold a set of configurations (one for each remap rule instance)
struct RemapConfigs {
  struct Item {
    TSOverridableConfigKey _name;
    TSRecordDataType _type;
    TSRecordData _data;
    int _data_len; // Used when data is a string
  };

  RemapConfigs() { memset(_items, 0, sizeof(_items)); };
  bool parse_file(const char *filename);
  bool parse_inline(const char *arg);

  Item _items[MAX_OVERRIDABLE_CONFIGS];
  int _current = 0;
};

// Helper function for the parser
inline TSRecordDataType
str_to_datatype(const char *str)
{
  TSRecordDataType type = TS_RECORDDATATYPE_NULL;

  if (!str || !*str) {
    return TS_RECORDDATATYPE_NULL;
  }

  if (!strcmp(str, "INT")) {
    type = TS_RECORDDATATYPE_INT;
  } else if (!strcmp(str, "STRING")) {
    type = TS_RECORDDATATYPE_STRING;
  } else if (!strcmp(str, "FLOAT")) {
    type = TS_RECORDDATATYPE_FLOAT;
  }

  return type;
}

// Parse an inline key=value config pair.
bool
RemapConfigs::parse_inline(const char *arg)
{
  const char *sep;
  std::string key;
  std::string value;

  TSOverridableConfigKey name;
  TSRecordDataType type;

  // Each token should be a configuration variable then a value, separated by '='.
  sep = strchr(arg, '=');
  if (sep == nullptr) {
    return false;
  }

  key   = std::string(arg, std::distance(arg, sep));
  value = std::string(sep + 1, std::distance(sep + 1, arg + strlen(arg)));

  if (TSHttpTxnConfigFind(key.c_str(), -1 /* len */, &name, &type) != TS_SUCCESS) {
    TSError("[%s] Invalid configuration variable '%s'", PLUGIN_NAME, key.c_str());
    return true;
  }

  switch (type) {
  case TS_RECORDDATATYPE_INT:
    _items[_current]._data.rec_int = strtoll(value.c_str(), nullptr, 10);
    break;
  case TS_RECORDDATATYPE_STRING:
    if (strcmp(value.c_str(), "NULL") == 0) {
      _items[_current]._data.rec_string = nullptr;
      _items[_current]._data_len        = 0;
    } else {
      _items[_current]._data.rec_string = TSstrdup(value.c_str());
      _items[_current]._data_len        = value.size();
    }
    break;
  case TS_RECORDDATATYPE_FLOAT:
    _items[_current]._data.rec_float = strtof(value.c_str(), nullptr);
    break;
  default:
    TSError("[%s] Configuration variable '%s' is of an unsupported type", PLUGIN_NAME, key.c_str());
    return false;
  }

  _items[_current]._name = name;
  _items[_current]._type = type;
  ++_current;
  return true;
}

// Config file parser, somewhat borrowed from P_RecCore.i
bool
RemapConfigs::parse_file(const char *filename)
{
  int line_num = 0;
  TSFile file;
  char buf[8192];
  TSOverridableConfigKey name;
  TSRecordDataType type, expected_type;

  std::string path;

  if (!filename || ('\0' == *filename)) {
    return false;
  }

  if (*filename == '/') {
    // Absolute path, just use it.
    path = filename;
  } else {
    // Relative path. Make it relative to the configuration directory.
    path = TSConfigDirGet();
    path += "/";
    path += filename;
  }

  if (nullptr == (file = TSfopen(path.c_str(), "r"))) {
    TSError("[%s] Could not open config file %s", PLUGIN_NAME, path.c_str());
    return false;
  }

  TSDebug(PLUGIN_NAME, "loading configuration file %s", path.c_str());

  while (nullptr != TSfgets(file, buf, sizeof(buf))) {
    char *ln, *tok;
    char *s = buf;

    ++line_num; // First line is #1 ...
    while (isspace(*s)) {
      ++s;
    }
    tok = strtok_r(s, " \t", &ln);

    // check for blank lines and comments
    if ((!tok) || (tok && ('#' == *tok))) {
      continue;
    }

    if (strncmp(tok, "CONFIG", 6)) {
      TSError("[%s] File %s, line %d: non-CONFIG line encountered", PLUGIN_NAME, path.c_str(), line_num);
      continue;
    }

    // Find the configuration name
    tok = strtok_r(nullptr, " \t", &ln);
    if (TSHttpTxnConfigFind(tok, -1, &name, &expected_type) != TS_SUCCESS) {
      TSError("[%s] File %s, line %d: %s is not a configuration variable or cannot be overridden", PLUGIN_NAME, path.c_str(),
              line_num, tok);
      continue;
    }

    // Find the type (INT or STRING only)
    tok = strtok_r(nullptr, " \t", &ln);
    if (TS_RECORDDATATYPE_NULL == (type = str_to_datatype(tok))) {
      TSError("[%s] file %s, line %d: only INT, STRING, and FLOAT types supported", PLUGIN_NAME, path.c_str(), line_num);
      continue;
    }

    if (type != expected_type) {
      TSError("[%s] file %s, line %d: mismatch between provide data type, and expected type", PLUGIN_NAME, path.c_str(), line_num);
      continue;
    }

    // Find the value (which depends on the type above)
    if (ln) {
      while (isspace(*ln)) {
        ++ln;
      }
      if ('\0' == *ln) {
        tok = nullptr;
      } else {
        tok = ln;
        while (*ln != '\0') {
          ++ln;
        }
        --ln;
        while (isspace(*ln) && (ln > tok)) {
          --ln;
        }
        ++ln;
        *ln = '\0';
      }
    } else {
      tok = nullptr;
    }
    if (!tok) {
      TSError("[%s] file %s, line %d: the configuration must provide a value", PLUGIN_NAME, path.c_str(), line_num);
      continue;
    }

    // Now store the new config
    switch (type) {
    case TS_RECORDDATATYPE_INT:
      _items[_current]._data.rec_int = strtoll(tok, nullptr, 10);
      break;
    case TS_RECORDDATATYPE_STRING:
      if (strcmp(tok, "NULL") == 0) {
        _items[_current]._data.rec_string = nullptr;
        _items[_current]._data_len        = 0;
      } else {
        _items[_current]._data.rec_string = TSstrdup(tok);
        _items[_current]._data_len        = strlen(tok);
      }
      break;
    case TS_RECORDDATATYPE_FLOAT:
      _items[_current]._data.rec_float = strtof(tok, nullptr);
      break;
    default:
      TSError("[%s] file %s, line %d: type not support (unheard of)", PLUGIN_NAME, path.c_str(), line_num);
      continue;
      break;
    }
    _items[_current]._name = name;
    _items[_current]._type = type;
    ++_current;
  }

  TSfclose(file);
  return (_current > 0);
}

///////////////////////////////////////////////////////////////////////////////
// Initialize the plugin as a remap plugin.
//
TSReturnCode
TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
{
  if (!api_info) {
    TSstrlcpy(errbuf, "[TSRemapInit] - Invalid TSRemapInterface argument", errbuf_size);
    return TS_ERROR;
  }

  if (api_info->size < sizeof(TSRemapInterface)) {
    TSstrlcpy(errbuf, "[TSRemapInit] - Incorrect size of TSRemapInterface structure", errbuf_size);
    return TS_ERROR;
  }

  TSDebug(PLUGIN_NAME, "remap plugin is successfully initialized");
  return TS_SUCCESS; /* success */
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSED */, int /* errbuf_size ATS_UNUSED */)
{
  if (argc < 3) {
    TSError("[%s] Unable to create remap instance, need configuration file", PLUGIN_NAME);
    return TS_ERROR;
  }

  RemapConfigs *conf = new (RemapConfigs);
  for (int i = 2; i < argc; ++i) {
    if (strchr(argv[i], '=') != nullptr) {
      // Parse as an inline key=value pair ...
      if (!conf->parse_inline(argv[i])) {
        goto fail;
      }
    } else {
      // Parse as a config file ...
      if (!conf->parse_file(argv[i])) {
        goto fail;
      }
    }
  }

  *ih = static_cast<void *>(conf);
  return TS_SUCCESS;

fail:
  delete conf;
  return TS_ERROR;
}

void
TSRemapDeleteInstance(void *ih)
{
  RemapConfigs *conf = static_cast<RemapConfigs *>(ih);

  for (int ix = 0; ix < conf->_current; ++ix) {
    if (TS_RECORDDATATYPE_STRING == conf->_items[ix]._type) {
      TSfree(conf->_items[ix]._data.rec_string);
    }
  }

  delete conf;
}

///////////////////////////////////////////////////////////////////////////////
// Main entry point when used as a remap plugin.
//
TSRemapStatus
TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo * /* rri ATS_UNUSED */)
{
  if (nullptr != ih) {
    RemapConfigs *conf = static_cast<RemapConfigs *>(ih);
    TSHttpTxn txnp     = static_cast<TSHttpTxn>(rh);

    for (int ix = 0; ix < conf->_current; ++ix) {
      switch (conf->_items[ix]._type) {
      case TS_RECORDDATATYPE_INT:
        TSHttpTxnConfigIntSet(txnp, conf->_items[ix]._name, conf->_items[ix]._data.rec_int);
        TSDebug(PLUGIN_NAME, "Setting config id %d to %" PRId64 "", conf->_items[ix]._name, conf->_items[ix]._data.rec_int);
        break;
      case TS_RECORDDATATYPE_STRING:
        TSHttpTxnConfigStringSet(txnp, conf->_items[ix]._name, conf->_items[ix]._data.rec_string, conf->_items[ix]._data_len);
        TSDebug(PLUGIN_NAME, "Setting config id %d to %s", conf->_items[ix]._name, conf->_items[ix]._data.rec_string);
        break;
      case TS_RECORDDATATYPE_FLOAT:
        TSHttpTxnConfigFloatSet(txnp, conf->_items[ix]._name, conf->_items[ix]._data.rec_int);
        TSDebug(PLUGIN_NAME, "Setting config id %d to %f", conf->_items[ix]._name, conf->_items[ix]._data.rec_float);
        break;
      default:
        break; // Error ?
      }
    }
  }

  return TSREMAP_NO_REMAP; // This plugin never rewrites anything.
}
