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

/**
 * @file plugin.cc
 * @brief traffic server plugin entry points.
 */
#include <sstream>

#include "ts/ts.h" /* ATS API */

#include "ts/remap.h" /* TSRemapInterface, TSRemapStatus, apiInfo */

#include "common.h"
#include "configs.h"
#include "fetch.h"
#include "fetch_policy.h"
#include "headers.h"
#include "evaluate.h"
#include "path.h"

static const char *
getEventName(TSEvent event)
{
  switch (event) {
  case TS_EVENT_HTTP_CONTINUE:
    return "TS_EVENT_HTTP_CONTINUE";
  case TS_EVENT_HTTP_ERROR:
    return "TS_EVENT_HTTP_ERROR";
  case TS_EVENT_HTTP_READ_REQUEST_HDR:
    return "TS_EVENT_HTTP_READ_REQUEST_HDR";
  case TS_EVENT_HTTP_OS_DNS:
    return "TS_EVENT_HTTP_OS_DNS";
  case TS_EVENT_HTTP_SEND_REQUEST_HDR:
    return "TS_EVENT_HTTP_SEND_REQUEST_HDR";
  case TS_EVENT_HTTP_READ_CACHE_HDR:
    return "TS_EVENT_HTTP_READ_CACHE_HDR";
  case TS_EVENT_HTTP_READ_RESPONSE_HDR:
    return "TS_EVENT_HTTP_READ_RESPONSE_HDR";
  case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
    return "TS_EVENT_HTTP_SEND_RESPONSE_HDR";
  case TS_EVENT_HTTP_REQUEST_TRANSFORM:
    return "TS_EVENT_HTTP_REQUEST_TRANSFORM";
  case TS_EVENT_HTTP_RESPONSE_TRANSFORM:
    return "TS_EVENT_HTTP_RESPONSE_TRANSFORM";
  case TS_EVENT_HTTP_SELECT_ALT:
    return "TS_EVENT_HTTP_SELECT_ALT";
  case TS_EVENT_HTTP_TXN_START:
    return "TS_EVENT_HTTP_TXN_START";
  case TS_EVENT_HTTP_TXN_CLOSE:
    return "TS_EVENT_HTTP_TXN_CLOSE";
  case TS_EVENT_HTTP_SSN_START:
    return "TS_EVENT_HTTP_SSN_START";
  case TS_EVENT_HTTP_SSN_CLOSE:
    return "TS_EVENT_HTTP_SSN_CLOSE";
  case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE:
    return "TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE";
  case TS_EVENT_HTTP_PRE_REMAP:
    return "TS_EVENT_HTTP_PRE_REMAP";
  case TS_EVENT_HTTP_POST_REMAP:
    return "TS_EVENT_HTTP_POST_REMAP";
  default:
    return "UNHANDLED";
  }
}

static const char *
getCacheLookupResultName(TSCacheLookupResult result)
{
  switch (result) {
  case TS_CACHE_LOOKUP_MISS:
    return "TS_CACHE_LOOKUP_MISS";
    break;
  case TS_CACHE_LOOKUP_HIT_STALE:
    return "TS_CACHE_LOOKUP_HIT_STALE";
    break;
  case TS_CACHE_LOOKUP_HIT_FRESH:
    return "TS_CACHE_LOOKUP_HIT_FRESH";
    break;
  case TS_CACHE_LOOKUP_SKIPPED:
    return "TS_CACHE_LOOKUP_SKIPPED";
    break;
  default:
    return "UNKNOWN_CACHE_LOOKUP_EVENT";
    break;
  }
}

/**
 * @brief Plugin initialization.
 * @param apiInfo remap interface info pointer
 * @param errBuf error message buffer
 * @param errBufSize error message buffer size
 * @return always TS_SUCCESS.
 */
TSReturnCode
TSRemapInit(TSRemapInterface * /* apiInfo ATS_UNUSED */, char * /* errBuf ATS_UNUSED */, int /* erroBufSize ATS_UNUSED */)
{
  return TS_SUCCESS;
}

/**
 * @brief Plugin instance data.
 */

struct PrefetchInstance {
  PrefetchInstance() = default;
  ;

private:
  PrefetchInstance(PrefetchInstance const &);
  void operator=(BgFetchState const &);

public:
  PrefetchConfig _config;
  BgFetchState  *_state = nullptr;
};

/**
 * brief Plugin transaction data.
 */
class PrefetchTxnData
{
public:
  PrefetchTxnData(PrefetchInstance *inst)
    : _inst(inst), _front(true), _firstPass(true), _fetchable(false), _status(TS_HTTP_STATUS_OK)
  {
  }

  bool
  firstPass() const
  {
    return _firstPass;
  }

  bool
  secondPass() const
  {
    return !_firstPass;
  }

  bool
  frontend() const
  {
    return _front;
  }

  bool
  backend() const
  {
    return !_front;
  }

  PrefetchInstance *_inst; /* Pointer to the plugin instance */

  bool _front;     /* front-end vs back-end */
  bool _firstPass; /* first vs second pass */

  /* saves state between hooks */
  String       _cachekey;  /* cache key */
  bool         _fetchable; /* saves the result of the attempt to fetch */
  TSHttpStatus _status;    /* status to return to the UA */
  String       _body;      /* body to return to the UA */
};

/**
 * @brief Expand+evaluate (in place) an expression surrounded with "{" and "}" and uses evaluate() to evaluate the math expression.
 *
 * @param s string containing an expression, i.e. "{3 + 4}"
 * @return void
 */
static void
expand(String &s, const EvalPolicy oflow)
{
  size_t cur = 0;
  while (String::npos != cur) {
    size_t start = s.find_first_of('{', cur);
    size_t stop  = s.find_first_of('}', start);

    if (String::npos != start && String::npos != stop) {
      s.replace(start, stop - start + 1, evaluate(s.substr(start + 1, stop - start - 1), oflow));
      cur = stop + 1;
    } else {
      cur = stop;
    }
  }
}

/**
 * @brief Get the cachekey used for the particular object in this transaction.
 *
 * @param txnp HTTP transaction structure
 * @param reqBuffer request TSMBuffer
 * @param destination string reference to where the result is to be appended.
 * @return true if success or false if failure
 */
bool
appendCacheKey(const TSHttpTxn txnp, const TSMBuffer reqBuffer, String &key)
{
  bool   ret    = false;
  TSMLoc keyLoc = TS_NULL_MLOC;
  if (TS_SUCCESS == TSUrlCreate(reqBuffer, &keyLoc)) {
    if (TS_SUCCESS == TSHttpTxnCacheLookupUrlGet(txnp, reqBuffer, keyLoc)) {
      int   urlLen = 0;
      char *url    = TSUrlStringGet(reqBuffer, keyLoc, &urlLen);
      if (nullptr != url) {
        key.append(url, urlLen);
        PrefetchDebug("cache key: %s", key.c_str());
        TSfree(static_cast<void *>(url));
        ret = true;
      }
    } else {
      PrefetchDebug("Failure lookup up cache url");
    }
    TSHandleMLocRelease(reqBuffer, TS_NULL_MLOC, keyLoc);
  } else {
    PrefetchDebug("Failure creating url");
  }

  if (!ret) {
    PrefetchError("failed to get cache key");
  }
  return ret;
}

/**
 * @brief Find out if the object was found fresh in cache.
 *
 * This function finely controls if the pre-fetch should be scheduled or not.
 * @param txnp HTTP transaction structure
 * @return true - hit fresh, false - miss/stale/skipped or error
 */
static bool
foundFresh(TSHttpTxn txnp)
{
  bool fresh = false;
  int  lookupStatus;
  if (TS_SUCCESS == TSHttpTxnCacheLookupStatusGet(txnp, &lookupStatus)) {
    PrefetchDebug("lookup status: %s", getCacheLookupResultName((TSCacheLookupResult)lookupStatus));
    if (TS_CACHE_LOOKUP_HIT_FRESH == lookupStatus) {
      fresh = true;
    }
  } else {
    /* Failed to get the lookup status,  likely a previous plugin already prepared the client response w/o a cache lookup,
     * we don't really know if the cache has a fresh object, so just don't trigger pre-fetch  */
    PrefetchDebug("failed to check cache-ability");
  }
  return fresh;
}

/**
 * @brief Check if the response from origin for N-th object is success (200 and 206)
 *
 * and only then schedule a pre-fetch for the next
 *
 * @param txnp HTTP transaction structure
 * @return true - yes, false - no
 */
bool
isResponseGood(TSHttpTxn txnp)
{
  bool      good = false;
  TSMBuffer respBuffer;
  TSMLoc    respHdrLoc;
  if (TS_SUCCESS == TSHttpTxnServerRespGet(txnp, &respBuffer, &respHdrLoc)) {
    TSHttpStatus status = TSHttpHdrStatusGet(respBuffer, respHdrLoc);
    PrefetchDebug("origin response code: %d", status);
    if (TS_HTTP_STATUS_PARTIAL_CONTENT == status || TS_HTTP_STATUS_OK == status) {
      good = true;
    }
    /* Release the response MLoc */
    TSHandleMLocRelease(respBuffer, TS_NULL_MLOC, respHdrLoc);
  } else {
    /* Failed to get the origin response, possible cause could be a origin connection problems or timeouts or
     * a previous plugin could have already prepared the client response w/o going to origin server */
    PrefetchDebug("failed to get origin response");
  }
  return good;
}

/**
 * @brief get the pristin URL path
 *
 * @param txnp HTTP transaction structure
 * @return pristine URL path
 */
static String
getPristineUrlPath(TSHttpTxn txnp)
{
  String    pristinePath;
  TSMLoc    pristineUrlLoc;
  TSMBuffer reqBuffer;

  if (TS_SUCCESS == TSHttpTxnPristineUrlGet(txnp, &reqBuffer, &pristineUrlLoc)) {
    int         pathLen = 0;
    const char *path    = TSUrlPathGet(reqBuffer, pristineUrlLoc, &pathLen);
    if (nullptr != path) {
      PrefetchDebug("path: '%.*s'", pathLen, path);
      pristinePath.assign(path, pathLen);
    } else {
      PrefetchError("failed to get pristine URL path");
    }
    TSHandleMLocRelease(reqBuffer, TS_NULL_MLOC, pristineUrlLoc);
  } else {
    PrefetchError("failed to get pristine URL");
  }
  return pristinePath;
}

/**
 * @brief get the pristin URL querystring
 *
 * @param txnp HTTP transaction structure
 * @return pristine URL querystring
 */
static String
getPristineUrlQuery(TSHttpTxn txnp)
{
  String    pristineQuery;
  TSMLoc    pristineUrlLoc;
  TSMBuffer reqBuffer;

  if (TS_SUCCESS == TSHttpTxnPristineUrlGet(txnp, &reqBuffer, &pristineUrlLoc)) {
    int         queryLen = 0;
    const char *query    = TSUrlHttpQueryGet(reqBuffer, pristineUrlLoc, &queryLen);
    if (nullptr != query) {
      PrefetchDebug("query: '%.*s'", queryLen, query);
      pristineQuery.assign(query, queryLen);
    }
    TSHandleMLocRelease(reqBuffer, TS_NULL_MLOC, pristineUrlLoc);
  } else {
    PrefetchError("failed to get pristine URL");
  }
  return pristineQuery;
}

/**
 * @brief Whether a single query parameter is the configured "<key>=..." parameter.
 */
static bool
isQueryKeyParam(const String &param, const String &key)
{
  return param.size() > key.size() && param.compare(0, key.size(), key) == 0 && param[key.size()] == '=';
}

/**
 * @brief Whether the query string contains the configured "<key>=..." parameter.
 */
static bool
hasQueryKeyParam(const String &query, const String &key)
{
  std::istringstream qs(query);
  String             param;
  while (getline(qs, param, '&')) {
    if (isQueryKeyParam(param, key)) {
      return true;
    }
  }
  return false;
}

static constexpr StringView CmcdHeader{"Cmcd-Request"};
static constexpr StringView CmcdNorFieldPrefix{"nor="};
static constexpr StringView CmcdNrrFieldPrefix{"nrr="};

/**
 * @brief Look for and return the nor field of any Cmcd-Request header
 *
 * @param txnp HTTP transaction structure
 * @param buffer request TSMBuffer
 * @param hdrloc request TSMLoc
 * @return unquoted relative cmcd path from the nor field
 *
 * If the 'nrr' field is encountered the 'nor' field will be ignored.
 *
 * sample header:
 * Cmcd-Request: mtp=103600,bl=153500,nor="14_176.mp4a"
 */
static String
getCmcdNor(const TSMBuffer buffer, const TSMLoc hdrloc)
{
  String relpath;
  bool   hasnrr = false; // don't prefetch if range request

  const TSMLoc cmcdloc = TSMimeHdrFieldFind(buffer, hdrloc, CmcdHeader.data(), CmcdHeader.length());
  if (TS_NULL_MLOC != cmcdloc) {
    // iterate through the fields
    const int cnt = TSMimeHdrFieldValuesCount(buffer, hdrloc, cmcdloc);
    for (int ind = 0; ind < cnt; ++ind) {
      int               flen = 0;
      const char *const fval = TSMimeHdrFieldValueStringGet(buffer, hdrloc, cmcdloc, ind, &flen);

      StringView fv(fval, flen);
      PrefetchDebug("cmcd-request field: '%.*s'", (int)fv.length(), fv.data());
      if (0 == fv.compare(0, CmcdNrrFieldPrefix.length(), CmcdNrrFieldPrefix)) {
        PrefetchDebug("cmcd-request nrr field encountered, skipping prefetch!");
        hasnrr = true;
        break;
      }

      if (0 == fv.compare(0, CmcdNorFieldPrefix.length(), CmcdNorFieldPrefix)) {
        fv.remove_prefix(CmcdNorFieldPrefix.length());
        if (fv.front() == '"') {
          fv.remove_prefix(1);
        }
        if (fv.back() == '"') {
          fv.remove_suffix(1);
        }

        PrefetchDebug("Extracted nor field: '%.*s'", (int)fv.length(), fv.data());

        // Undo any percent encoding
        char   buf[8192];
        size_t blen = sizeof(buf);
        if (TS_SUCCESS == TSStringPercentDecode(fv.data(), fv.length(), buf, blen, &blen)) {
          relpath.assign(buf, blen);
        } else {
          PrefetchDebug("Error percent decoding nor field: '%.*s'", (int)fv.length(), fv.data());
        }
      }
    }
    TSHandleMLocRelease(buffer, hdrloc, cmcdloc);
  } else {
    PrefetchDebug("No Cmcd-Request header found");
  }

  // don't prefetch if range request
  if (hasnrr) {
    relpath.clear();
  }

  return relpath;
}

/**
 * @brief short-cut to set the response .
 */
TSEvent
shortcutResponse(PrefetchTxnData *data, TSHttpStatus status, const char *body, TSEvent event)
{
  data->_status = status;
  data->_body.assign(body);
  return event;
}

/**
 * @brief Checks if we are still supposed to schedule a background fetch based on whether the object is in the cache.
 * It is 'fetchable' only if not a fresh hit.
 *
 * @param txnp HTTP transaction structure
 * @param data transaction data
 * @return true if fetchable and false if not.
 */
static bool
isFetchable(TSHttpTxn txnp, PrefetchTxnData *data)
{
  bool          fetchable = false;
  BgFetchState *state     = data->_inst->_state;
  if (!foundFresh(txnp)) {
    /* Schedule fetch only if not in cache */
    PrefetchDebug("object to be fetched");
    fetchable = true;
  } else {
    PrefetchDebug("object already in cache or to be skipped");
    state->incrementMetric(FETCH_ALREADY_CACHED);
    state->incrementMetric(FETCH_TOTAL);
  }
  return fetchable;
}

/**
 * @brief Find out if the current response to trigger a background prefetch.
 *
 * Pre-fetch only on HTTP codes 200 and 206 or object found in cache (previous good response)
 *
 * @param txnp HTTP transaction structure
 * @return true - trigger prefetch, false - don't trigger.
 */
static bool
respToTriggerPrefetch(TSHttpTxn txnp)
{
  bool trigger = false;
  if (foundFresh(txnp)) {
    /* If found in cache and fresh trigger next (same as good response from origin) */
    PrefetchDebug("trigger background fetch (cached)");
    trigger = true;
  } else if (isResponseGood(txnp)) {
    /* Trigger all necessary background fetches based on the next path pattern */
    PrefetchDebug("trigger background fetch (good origin response)");
    trigger = true;
  } else {
    PrefetchDebug("don't trigger background fetch");
  }
  return trigger;
}

/**
 * @brief Callback function that handles necessary foreground / background fetch operations.
 *
 * @param contp continuation associated with this function.
 * @param event corresponding event triggered at different hooks.
 * @param edata HTTP transaction structures.
 * @return always 0
 */
int
contHandleFetch(const TSCont contp, TSEvent event, void *edata)
{
  PrefetchTxnData *data      = static_cast<PrefetchTxnData *>(TSContDataGet(contp));
  TSHttpTxn        txnp      = static_cast<TSHttpTxn>(edata);
  PrefetchConfig  &config    = data->_inst->_config;
  BgFetchState    *state     = data->_inst->_state;
  TSMBuffer        reqBuffer = nullptr;
  TSMLoc           reqHdrLoc = TS_NULL_MLOC;

  PrefetchDebug("event: %s (%d)", getEventName(event), event);

  TSEvent retEvent = TS_EVENT_HTTP_CONTINUE;

  // For these cases we need to access the client request
  switch (event) {
  case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE:
  case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
    if (TS_SUCCESS != TSHttpTxnClientReqGet(txnp, &reqBuffer, &reqHdrLoc)) {
      PrefetchError("failed to get client request");
      TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
      return 0;
    }
    break;
  default:
    break;
  }

  switch (event) {
  case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: {
    /* Use the cache key (multiple URIs can map to one key). CACHE_LOOKUP_COMPLETE is
     * the earliest hook where TSHttpTxnCacheLookupUrlGet returns a populated URL. */
    if (data->frontend() && data->secondPass()) {
      /* Create a separate cache key name space to be used only for front-end and second-pass fetch policy checks. */
      data->_cachekey.assign("/prefetch");
    }
    if (!appendCacheKey(txnp, reqBuffer, data->_cachekey)) {
      PrefetchError("failed to get the cache key");
      TSHandleMLocRelease(reqBuffer, TS_NULL_MLOC, reqHdrLoc);
      TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
      return 0;
    }

    if (data->frontend()) {
      /* front-end instance */
      if (data->firstPass()) {
        /* first-pass */
        if (!config.isExactMatch()) {
          data->_fetchable = state->acquire(data->_cachekey);
          PrefetchDebug("request is %s fetchable", data->_fetchable ? " " : " not ");
        }
      } else {
        /* second-pass */
        if (state->acquire(data->_cachekey)) {
          if (state->uniqueAcquire(data->_cachekey)) {
            data->_fetchable = true;
          } else {
            state->release(data->_cachekey);
          }
        }
        PrefetchDebug("request is %s fetchable", data->_fetchable ? " " : " not ");

        if (isFetchable(txnp, data)) {
          if (!data->_fetchable) {
            /* Cancel the requested fetch */
            retEvent = shortcutResponse(data, TS_HTTP_STATUS_ALREADY_REPORTED, "fetch not scheduled\n", TS_EVENT_HTTP_ERROR);
          } else {
            /* Fetch */
          }
        } else {
          retEvent = shortcutResponse(data, TS_HTTP_STATUS_ALREADY_REPORTED, "fetch not scheduled\n", TS_EVENT_HTTP_ERROR);
        }
      }
    } else {
      /* back-end instance */
      if (data->firstPass()) {
        if (isFetchable(txnp, data)) {
          if (BgFetch::schedule(state, config, /* askPermission */ true, reqBuffer, reqHdrLoc, txnp, nullptr, 0, data->_cachekey)) {
            retEvent = shortcutResponse(data, TS_HTTP_STATUS_OK, "fetch scheduled\n", TS_EVENT_HTTP_ERROR);
          } else {
            retEvent = shortcutResponse(data, TS_HTTP_STATUS_ALREADY_REPORTED, "fetch not scheduled\n", TS_EVENT_HTTP_ERROR);
          }
        } else {
          retEvent = shortcutResponse(data, TS_HTTP_STATUS_ALREADY_REPORTED, "fetch not scheduled\n", TS_EVENT_HTTP_ERROR);
        }
      }
    }
  } break;

  case TS_EVENT_HTTP_SEND_RESPONSE_HDR: {
    if (data->frontend()) {
      /* front-end instance */

      const String currentPath   = getPristineUrlPath(txnp);
      const String currentQuery  = getPristineUrlQuery(txnp);
      bool         hasValidQuery = false;

      // If there is a --fetch-query defined in the config, and that parameter is present in the querystring, assume it
      // is valid, and prefer the --fetch-query over the --fetch-path-pattern(s).
      if (!config.getQueryKeyName().empty() && hasQueryKeyParam(currentQuery, config.getQueryKeyName())) {
        PrefetchDebug("Setting hasValidQuery to true");
        hasValidQuery = true;
      }

      if (data->firstPass() && data->_fetchable && respToTriggerPrefetch(txnp)) {
        // If configured to handle Cmcd-Request nor field.
        // This still allows other prefetch configurations to work.
        if (config.isCmcdNor()) {
          PrefetchDebug("Considering cmcd nor request");

          TSAssert(nullptr != reqBuffer);
          TSAssert(TS_NULL_MLOC != reqHdrLoc);

          const String relpath = getCmcdNor(reqBuffer, reqHdrLoc);
          if (!relpath.empty()) {
            PrefetchDebug("Current path: '%s'", currentPath.c_str());
            PrefetchDebug("Parsed cmcd nor relpath: '%s'", relpath.c_str());

            SafeRelativeFetchPath nextPath;
            if (!makeSafeRelativeFetchPath(currentPath, relpath, nextPath)) {
              PrefetchDebug("skipping unsafe cmcd nor path: '%s'", relpath.c_str());
            } else {
              PrefetchDebug("Next cmcd nor path: '%s'", nextPath.path.c_str());

              constexpr bool askPermission = false;
              constexpr bool removeQuery   = true;
              BgFetch::schedule(state, config, askPermission, reqBuffer, reqHdrLoc, txnp, nextPath.path.c_str(),
                                nextPath.path.length(), data->_cachekey, removeQuery,
                                nextPath.hasQuery ? nextPath.query.c_str() : nullptr, nextPath.query.length());
            }
          }
        }

        if (!hasValidQuery && !config.getNextPath().empty()) {
          /* Trigger all necessary background fetches based on the next path pattern */

          if (!currentPath.empty()) {
            const unsigned total       = config.getFetchCount();
            String         workingPath = currentPath;
            for (unsigned i = 0; i < total; ++i) {
              PrefetchDebug("generating prefetch request %d/%d", i + 1, total);
              String expandedPath;

              if (config.getNextPath().replace(workingPath, expandedPath)) {
                if (expandedPath.empty()) {
                  /* A replacement that collapses to empty (e.g. every referenced group was optional and
                   * absent) would otherwise be scheduled with a zero-length path, which BgFetch skips --
                   * leaving the original request path in place and prefetching the pristine URL itself.
                   * Stop rather than issue that self-prefetch. Report once per instance; whether the
                   * replacement collapses depends on the request, so this recurs per transaction. */
                  if (config.shouldReportEmptyPath()) {
                    PrefetchError("prefetch pattern produced an empty path; check the fetch-path-pattern replacement");
                  } else {
                    PrefetchDebug("prefetch pattern produced an empty path");
                  }
                  break;
                }
                PrefetchDebug("replaced: %s", expandedPath.c_str());
                expand(expandedPath, config.getFetchOverflow());
                PrefetchDebug("expanded: %s cachekey: %s", expandedPath.c_str(), data->_cachekey.c_str());

                BgFetch::schedule(state, config, /* askPermission */ false, reqBuffer, reqHdrLoc, txnp, expandedPath.c_str(),
                                  expandedPath.length(), data->_cachekey);
              } else {
                /* We should be here only if the pattern replacement fails (match already checked) */
                PrefetchError("failed to process the pattern");

                /* If the first or any matches fails there must be something wrong so don't continue */
                break;
              }
              workingPath.assign(expandedPath);
            }
          } else {
            PrefetchDebug("failed to get current path");
          }
        } else if (hasValidQuery) {
          /* Trigger all necessary background fetches based on the query string(s) */

          PrefetchDebug("currentQuery: %s", currentQuery.c_str());
          const String      &queryKeyName = config.getQueryKeyName();
          const size_t       keyLen       = queryKeyName.size();
          unsigned           done         = 1;
          std::istringstream cStringStream(currentQuery);
          String             param;

          while (getline(cStringStream, param, '&')) {
            if (!isQueryKeyParam(param, config.getQueryKeyName())) {
              continue;
            }
            String nextFile = param.substr(keyLen + 1); // +1 for the '='
            if (nextFile.empty()) {
              PrefetchDebug("skipping empty query prefetch path");
              continue;
            }
            if (config.getFetchCount() < done++) {
              break;
            }
            SafeRelativeFetchPath nextPath;
            if (!makeSafeRelativeFetchPath(currentPath, nextFile, nextPath)) {
              PrefetchDebug("skipping unsafe query prefetch path: '%s'", nextFile.c_str());
              continue;
            }

            PrefetchDebug("nextPath %s, cacheKey %s", nextPath.path.c_str(), data->_cachekey.c_str());
            BgFetch::schedule(state, config, /* askPermission */ false, reqBuffer, reqHdrLoc, txnp, nextPath.path.c_str(),
                              nextPath.path.length(), data->_cachekey, /* removeQuery */ false,
                              nextPath.hasQuery ? nextPath.query.c_str() : nullptr, nextPath.query.length());
          }
        }
      }
    }

    if ((data->backend() && data->firstPass()) || (data->frontend() && data->secondPass() && !data->_body.empty())) {
      TSMBuffer bufp;
      TSMLoc    hdrLoc;

      if (TS_SUCCESS == TSHttpTxnClientRespGet(txnp, &bufp, &hdrLoc)) {
        const char *reason    = TSHttpHdrReasonLookup(data->_status);
        int         reasonLen = strlen(reason);
        TSHttpHdrStatusSet(bufp, hdrLoc, data->_status, txnp, PLUGIN_NAME);
        TSHttpHdrReasonSet(bufp, hdrLoc, reason, reasonLen);
        PrefetchDebug("set response: %d %.*s '%s'", data->_status, reasonLen, reason, data->_body.c_str());

        size_t bufsize = data->_body.length() + 1;
        char  *buf     = static_cast<char *>(TSmalloc(bufsize));
        memcpy(buf, data->_body.c_str(), bufsize);
        TSHttpTxnErrorBodySet(txnp, buf, strlen(buf), nullptr);

        setHeader(bufp, hdrLoc, TS_MIME_FIELD_CACHE_CONTROL, TS_MIME_LEN_CACHE_CONTROL, TS_HTTP_VALUE_NO_STORE,
                  TS_HTTP_LEN_NO_STORE);

        TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdrLoc);
      } else {
        PrefetchError("failed to retrieve client response header");
      }
    }
  } break;

  case TS_EVENT_HTTP_TXN_CLOSE: {
    if (data->_fetchable) {
      if (data->frontend()) {
        /* front-end */
        if (data->firstPass()) {
          /* first-pass */
          if (!config.isExactMatch()) {
            state->release(data->_cachekey);
          }
        } else {
          /* second-pass */
          state->uniqueRelease(data->_cachekey);
          state->release(data->_cachekey);
        }
      }
    }

    /* Destroy the txn continuation and its data */
    delete data;
    TSContDestroy(contp);
  } break;

  default: {
    PrefetchError("unhandled event: %s(%d)", getEventName(event), event);
  } break;
  }

  /* Release the request MLoc */
  if (event == TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE || event == TS_EVENT_HTTP_SEND_RESPONSE_HDR) {
    TSHandleMLocRelease(reqBuffer, TS_NULL_MLOC, reqHdrLoc);
  }

  /* Reenable and continue with the state machine. */
  TSHttpTxnReenable(txnp, retEvent);
  return 0;
}

/**
 * @brief Plugin new instance entry point.
 *
 * Processes the configuration and initializes the plugin instance.
 * @param argc plugin arguments number
 * @param argv plugin arguments
 * @param instance new plugin instance pointer (initialized in this function)
 * @param errBuf error message buffer
 * @param errBufSize error message buffer size
 * @return TS_SUCCES if success or TS_ERROR if failure
 */
TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **instance, char * /* errBuf ATS_UNUSED */, int /* errBufSize ATS_UNUSED */)
{
  bool failed = true;

  PrefetchInstance *inst = new PrefetchInstance();
  if (nullptr != inst) {
    if (inst->_config.init(argc, argv)) {
      inst->_state = BgFetchStates::get()->getStateByName(inst->_config.getNameSpace());
      if (nullptr != inst->_state) {
        failed = !inst->_state->init(inst->_config);
      }
    }
  }

  if (failed) {
    PrefetchError("failed to initialize the plugin");
    delete inst;
    *instance = nullptr;
    return TS_ERROR;
  }

  *instance = inst;
  return TS_SUCCESS;
}

/**
 * @brief Plugin instance deletion clean-up entry point.
 * @param plugin instance pointer.
 */
void
TSRemapDeleteInstance(void *instance)
{
  PrefetchInstance *inst = static_cast<PrefetchInstance *>(instance);
  delete inst;
}

/**
 * @brief Organizes the background fetch by registering necessary hooks, by identifying front-end vs back-end, first vs second
 * pass.
 *
 * Remap is never done, continue with next in chain.
 * @param instance plugin instance pointer
 * @param txnp transaction handle
 * @param rri remap request info pointer
 * @return always TSREMAP_NO_REMAP
 */
TSRemapStatus
TSRemapDoRemap(void *instance, TSHttpTxn txnp, TSRemapRequestInfo *rri)
{
  PrefetchInstance *inst = static_cast<PrefetchInstance *>(instance);

  if (nullptr != inst) {
    PrefetchConfig &config = inst->_config;

    int           methodLen = 0;
    const char   *method    = TSHttpHdrMethodGet(rri->requestBufp, rri->requestHdrp, &methodLen);
    const String &header    = config.getApiHeader();
    if (nullptr != method && methodLen == TS_HTTP_LEN_GET && 0 == memcmp(TS_HTTP_METHOD_GET, method, TS_HTTP_LEN_GET)) {
      bool front     = config.isFront();
      bool firstPass = false;
      if (headerExist(rri->requestBufp, rri->requestHdrp, header.c_str(), header.length())) {
        PrefetchDebug("%s: found %.*s", front ? "front-end" : "back-end", (int)header.length(), header.c_str());
        /* On front-end: presence of header means second-pass, on back-end means first-pass. */
        firstPass = !front;
      } else {
        /* On front-end: lack of header means first-pass, on back-end means second-pass. */
        firstPass = front;
      }

      /* Make sure we handle only URLs that match the path pattern on the front-end + first-pass, cancel otherwise */
      bool handleFetch = true;
      if (front && firstPass && !config.isCmcdNor()) {
        /* Front-end plug-in instance + first pass. */
        if (config.getNextPath().empty()) {
          /* No next path pattern specified then pass this request untouched. */
          PrefetchDebug("next object pattern not specified, skip");
          handleFetch = false;
        } else {
          /* Next path pattern specified hence try to match. */
          String pristinePath = getPristineUrlPath(txnp);
          if (!pristinePath.empty()) {
            if (config.getNextPath().match(pristinePath)) {
              /* Matched - handle the request */
              PrefetchDebug("matched next object pattern");
              inst->_state->incrementMetric(FETCH_MATCH_YES);
            } else {
              /* Next path pattern specified but did not match. */
              PrefetchDebug("failed to match next object pattern, skip");
              inst->_state->incrementMetric(FETCH_MATCH_NO);
              handleFetch = false;
            }
          } else {
            PrefetchDebug("failed to get path to (pre)match");
          }

          const String &queryKey = config.getQueryKeyName();
          if (!handleFetch && !queryKey.empty() && hasQueryKeyParam(getPristineUrlQuery(txnp), queryKey)) {
            PrefetchDebug("handling for query-key: %s", queryKey.c_str());
            handleFetch = true;
          }
        }
      }

      if (handleFetch) {
        PrefetchTxnData *data = new PrefetchTxnData(inst);
        if (nullptr != data) {
          data->_front     = front;
          data->_firstPass = firstPass;

          TSCont cont = TSContCreate(contHandleFetch, TSMutexCreate());
          TSContDataSet(cont, static_cast<void *>(data));

          TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, cont);
          TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, cont);
          TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, cont);
        } else {
          PrefetchError("failed to allocate transaction data object");
        }
      }
    } else {
      PrefetchDebug("not a GET method (%.*s), skipping", methodLen, method);
    }
  } else {
    PrefetchError("could not get prefetch instance");
  }

  return TSREMAP_NO_REMAP;
}
