/** @file

  This plugin allows retrying requests against different destinations.

  @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.
 */
#include <ts/ts.h>
#include <ts/remap.h>
#include <ts/experimental.h>
#include <cstdlib>
#include <cstdio>
#include <getopt.h>
#include <cstring>
#include <string>
#include <iterator>
#include <map>

// Constants and some declarations
const char PLUGIN_NAME[] = "escalate";
static int EscalateResponse(TSCont, TSEvent, void *);

//////////////////////////////////////////////////////////////////////////////////////////
// Hold information about the escalation / retry states for a remap rule.
//
struct EscalationState {
  enum RetryType {
    RETRY_URL,
    RETRY_HOST,
  };

  struct RetryInfo {
    RetryType type;
    std::string target;
  };

  using StatusMapType = std::map<unsigned int, RetryInfo>;

  EscalationState()
  {
    cont = TSContCreate(EscalateResponse, nullptr);
    TSContDataSet(cont, this);
  }

  ~EscalationState() { TSContDestroy(cont); }
  TSCont cont;
  StatusMapType status_map;
  bool use_pristine = false;
};

// Little helper function, to update the Host portion of a URL, and stringify the result.
// Returns the URL string, and updates url_len with the length.
char *
MakeEscalateUrl(TSMBuffer mbuf, TSMLoc url, const char *host, size_t host_len, int &url_len)
{
  char *url_str = nullptr;

  // Update the request URL with the new Host to try.
  TSUrlHostSet(mbuf, url, host, host_len);
  url_str = TSUrlStringGet(mbuf, url, &url_len);
  TSDebug(PLUGIN_NAME, "Setting new URL to %.*s", url_len, url_str);

  return url_str;
}

//////////////////////////////////////////////////////////////////////////////////////////
// Main continuation for the plugin, examining an origin response for a potential retry.
//
static int
EscalateResponse(TSCont cont, TSEvent event, void *edata)
{
  TSHttpTxn txn       = static_cast<TSHttpTxn>(edata);
  EscalationState *es = static_cast<EscalationState *>(TSContDataGet(cont));
  EscalationState::StatusMapType::const_iterator entry;
  TSMBuffer mbuf;
  TSMLoc hdrp, url;
  TSHttpStatus status;
  char *url_str = nullptr;
  int url_len, tries;

  TSAssert(event == TS_EVENT_HTTP_READ_RESPONSE_HDR);

  // First, we need the server response ...
  if (TS_SUCCESS != TSHttpTxnServerRespGet(txn, &mbuf, &hdrp)) {
    goto no_action;
  }

  tries = TSHttpTxnRedirectRetries(txn);
  if (0 != tries) { // ToDo: Future support for more than one retry-URL
    goto no_action;
  }
  TSDebug(PLUGIN_NAME, "This is try %d, proceeding", tries);

  // Next, the response status ...
  status = TSHttpHdrStatusGet(mbuf, hdrp);
  TSHandleMLocRelease(mbuf, TS_NULL_MLOC, hdrp); // Don't need this any more

  // See if we have an escalation retry config for this response code
  entry = es->status_map.find(static_cast<unsigned>(status));
  if (entry == es->status_map.end()) {
    goto no_action;
  }

  TSDebug(PLUGIN_NAME, "Found an entry for HTTP status %u", static_cast<unsigned>(status));
  if (EscalationState::RETRY_URL == entry->second.type) {
    url_str = TSstrdup(entry->second.target.c_str());
    url_len = entry->second.target.size();
    TSDebug(PLUGIN_NAME, "Setting new URL to %.*s", url_len, url_str);
  } else if (EscalationState::RETRY_HOST == entry->second.type) {
    if (es->use_pristine) {
      if (TS_SUCCESS == TSHttpTxnPristineUrlGet(txn, &mbuf, &url)) {
        url_str = MakeEscalateUrl(mbuf, url, entry->second.target.c_str(), entry->second.target.size(), url_len);
        TSHandleMLocRelease(mbuf, TS_NULL_MLOC, url);
      }
    } else {
      if (TS_SUCCESS == TSHttpTxnClientReqGet(txn, &mbuf, &hdrp)) {
        if (TS_SUCCESS == TSHttpHdrUrlGet(mbuf, hdrp, &url)) {
          url_str = MakeEscalateUrl(mbuf, url, entry->second.target.c_str(), entry->second.target.size(), url_len);
        }
        // Release the request MLoc
        TSHandleMLocRelease(mbuf, TS_NULL_MLOC, hdrp);
      }
    }
  }

  // Now update the Redirect URL, if set
  if (url_str) {
    TSHttpTxnRedirectUrlSet(txn, url_str, url_len); // Transfers ownership
  }

// Set the transaction free ...
no_action:
  TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
  return TS_EVENT_NONE;
}

TSReturnCode
TSRemapInit(TSRemapInterface * /* api */, char * /* errbuf */, int /* bufsz */)
{
  return TS_SUCCESS;
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **instance, char *errbuf, int errbuf_size)
{
  EscalationState *es = new EscalationState();

  // The first two arguments are the "from" and "to" URL string. We can just
  // skip those, since we only ever remap on the error path.
  for (int i = 2; i < argc; ++i) {
    char *sep, *token, *save;

    // Ugly, but we set the precedence before with non-command line parsing of args
    if (0 == strncasecmp(argv[i], "--pristine", 10)) {
      es->use_pristine = true;
    } else {
      // Each token should be a status code then a URL, separated by ':'.
      sep = strchr(argv[i], ':');
      if (sep == nullptr) {
        snprintf(errbuf, errbuf_size, "malformed status:target config: %s", argv[i]);
        goto fail;
      }

      *sep = '\0';
      ++sep; // Skip over the ':' (which is now \0)

      // OK, we have a valid status/URL pair.
      EscalationState::RetryInfo info;

      info.target = sep;
      if (std::string::npos != info.target.find('/')) {
        info.type = EscalationState::RETRY_URL;
        TSDebug(PLUGIN_NAME, "Creating Redirect rule with URL = %s", sep);
      } else {
        info.type = EscalationState::RETRY_HOST;
        TSDebug(PLUGIN_NAME, "Creating Redirect rule with Host = %s", sep);
      }

      for (token = strtok_r(argv[i], ",", &save); token; token = strtok_r(nullptr, ",", &save)) {
        unsigned status = strtol(token, nullptr, 10);

        if (status < 100 || status > 599) {
          snprintf(errbuf, errbuf_size, "invalid status code: %.*s", static_cast<int>(std::distance(argv[i], sep)), argv[i]);
          goto fail;
        }

        TSDebug(PLUGIN_NAME, "      added status = %d to rule", status);
        es->status_map[status] = info;
      }
    }
  }

  *instance = es;
  return TS_SUCCESS;

fail:
  delete es;
  return TS_ERROR;
}

void
TSRemapDeleteInstance(void *instance)
{
  delete static_cast<EscalationState *>(instance);
}

TSRemapStatus
TSRemapDoRemap(void *instance, TSHttpTxn txn, TSRemapRequestInfo * /* rri */)
{
  EscalationState *es = static_cast<EscalationState *>(instance);

  TSHttpTxnHookAdd(txn, TS_HTTP_READ_RESPONSE_HDR_HOOK, es->cont);
  return TSREMAP_NO_REMAP;
}
