/** @file

  Per-remap purge RESTful API for stateful generation ID management.

  @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 <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/types.h>

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

static const char *PLUGIN_NAME = "remap_purge";
static const char *DEFAULT_DIR = "var/trafficserver"; /* Not perfect, but no better API) */

typedef struct PurgeInstance_t {
  char *id;
  char *secret;
  int secret_len;
  char *header;
  int header_len;
  char *state_file;
  bool allow_get;
  int64_t gen_id;
  TSMutex lock;
} PurgeInstance;

static char *
make_state_path(const char *filename)
{
  if ('/' == *filename) {
    return TSstrdup(filename);
  } else {
    char buf[8192];
    const char *dir = TSInstallDirGet();

    snprintf(buf, sizeof(buf), "%s/%s/%s", dir, DEFAULT_DIR, PLUGIN_NAME);
    if (-1 == mkdir(buf, S_IRWXU)) {
      if (EEXIST != errno) {
        TSError("[%s] Unable to create directory %s: %s (%d)", PLUGIN_NAME, buf, strerror(errno), errno);
        return NULL;
      }
    }
    snprintf(buf, sizeof(buf), "%s/%s/%s/%s.genid", dir, DEFAULT_DIR, PLUGIN_NAME, filename);
    return TSstrdup(buf);
  }

  return NULL;
}

/* Constructor and destructor for the PurgeInstance */
static void
init_purge_instance(PurgeInstance *purge)
{
  FILE *file = fopen(purge->state_file, "r");

  if (file) {
    if (fscanf(file, "%" PRId64 "", &purge->gen_id) > 0) {
      TSDebug(PLUGIN_NAME, "Read genID from %s for %s", purge->state_file, purge->id);
    }
    fclose(file);
  } else {
    TSError("[%s] Can not open file %s: %s (%d)", PLUGIN_NAME, purge->state_file, strerror(errno), errno);
  }

  purge->lock = TSMutexCreate();
}

static void
delete_purge_instance(PurgeInstance *purge)
{
  if (purge) {
    TSfree(purge->id);
    TSfree(purge->state_file);
    TSfree(purge->secret);
    TSfree(purge->header);
    TSMutexDestroy(purge->lock);
    TSfree(purge);
  }
}

/* This is where we start the PURGE events, setting up the transaction to fail,
   and bump the generation ID, and finally save the state. */
static void
update_purge_state(PurgeInstance *purge)
{
  FILE *file;

  TSMutexLock(purge->lock);

  ++purge->gen_id;
  TSDebug(PLUGIN_NAME, "Bumping the Generation ID to %" PRId64 " for %s", purge->gen_id, purge->id);

  if ((file = fopen(purge->state_file, "w"))) {
    TSDebug(PLUGIN_NAME, "\tsaving state to %s", purge->state_file);
    fprintf(file, "%" PRId64 "", purge->gen_id);
    fclose(file);
  } else {
    TSError("[%s] Unable to save state to file %s: errno=%d", PLUGIN_NAME, purge->state_file, errno);
  }

  TSMutexUnlock(purge->lock);
}

/* Before we can send the response, we want to modify it to a "200 OK" again,
   and produce some reasonable body output. */
static TSReturnCode
on_send_response_header(TSHttpTxn txnp, TSCont contp, PurgeInstance *purge)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc;

  TSDebug(PLUGIN_NAME, "Fixing up the response on the successful PURGE");
  if (TS_SUCCESS == TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc)) {
    char response[1024];
    int len = snprintf(response, sizeof(response), "PURGED %s\r\n\r\n", purge->id);

    TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_OK);
    TSHttpHdrReasonSet(bufp, hdr_loc, "OK", 2);
    TSHttpTxnErrorBodySet(txnp, TSstrdup(response), len >= (int)sizeof(response) ? (int)sizeof(response) - 1 : len, NULL);

    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
  } else {
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
  }
  TSContDestroy(contp);

  return TS_SUCCESS;
}

/* This is the main continuation, triggered after DoRemap has decided we should
   handle this request internally. */
static int
purge_cont(TSCont contp, TSEvent event, void *edata)
{
  TSHttpTxn txnp       = (TSHttpTxn)edata;
  PurgeInstance *purge = (PurgeInstance *)TSContDataGet(contp);

  switch (event) {
  case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
    return on_send_response_header(txnp, contp, purge);
    break;

  default:
    TSDebug(PLUGIN_NAME, "Unexpected event: %d", event);
    break;
  }

  return TS_SUCCESS;
}

static void
handle_purge(TSHttpTxn txnp, PurgeInstance *purge)
{
  TSMBuffer reqp;
  TSMLoc hdr_loc = NULL, url_loc = NULL;
  bool should_purge = false;

  if (TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) {
    int method_len     = 0;
    const char *method = TSHttpHdrMethodGet(reqp, hdr_loc, &method_len);

    if ((TS_HTTP_METHOD_PURGE == method) || ((TS_HTTP_METHOD_GET == method) && purge->allow_get)) {
      /* First see if we require the "secret" to be passed in a header, and then use that */
      if (purge->header) {
        TSMLoc field_loc = TSMimeHdrFieldFind(reqp, hdr_loc, purge->header, purge->header_len);

        if (field_loc) {
          const char *header;
          int header_len;

          header = TSMimeHdrFieldValueStringGet(reqp, hdr_loc, field_loc, -1, &header_len);
          TSDebug(PLUGIN_NAME, "Checking for %.*s == %s ?", header_len, header, purge->secret);
          if (header && (header_len == purge->secret_len) && !memcmp(header, purge->secret, header_len)) {
            should_purge = true;
          }
          TSHandleMLocRelease(reqp, hdr_loc, field_loc);
        }
      } else {
        /* We are matching on the path component instead of a header */
        if (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc)) {
          int path_len     = 0;
          const char *path = TSUrlPathGet(reqp, url_loc, &path_len);

          TSDebug(PLUGIN_NAME, "Checking PATH = %.*s", path_len, path);
          if (path && (path_len >= purge->secret_len)) {
            int s_path = path_len - 1;

            /* Find the last /, essentially memrchr (which does not exist on macOS) */
            while ((s_path >= 0) && ('/' != path[s_path])) {
              --s_path;
            }

            if (((path_len - s_path - 1) == purge->secret_len) &&
                !memcmp(s_path > 0 ? path + s_path + 1 : path, purge->secret, purge->secret_len)) {
              should_purge = true;
            }
          }
          TSHandleMLocRelease(reqp, hdr_loc, url_loc);
        }
      }
    }
    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
  }

  /* Setup the continuation to handle this request if appropriate, if not, set the GenID if needed */
  if (should_purge) {
    TSCont cont = TSContCreate(purge_cont, TSMutexCreate());

    TSDebug(PLUGIN_NAME, "Setting up continuation for PURGE operation");
    TSContDataSet(cont, purge);
    TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, cont);
    update_purge_state(purge);
  } else if (purge->gen_id > 0) {
    TSDebug(PLUGIN_NAME, "Setting request gen_id to %" PRId64, purge->gen_id);
    TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_CACHE_GENERATION, purge->gen_id);
  }
}

TSReturnCode
TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
{
  TSDebug(PLUGIN_NAME, "initialized");
  return TS_SUCCESS;
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuf, int errbuf_size)
{
  char *id                             = argv[0]; /* The ID is default to the "from" URL, so save it */
  PurgeInstance *purge                 = TSmalloc(sizeof(PurgeInstance));
  static const struct option longopt[] = {
    {(char *)"id", required_argument, NULL, 'i'},     {(char *)"secret", required_argument, NULL, 's'},
    {(char *)"header", required_argument, NULL, 'h'}, {(char *)"state-file", required_argument, NULL, 'f'},
    {(char *)"allow-get", no_argument, NULL, 'a'},    {NULL, no_argument, NULL, '\0'},
  };

  memset(purge, 0, sizeof(PurgeInstance));

  // The first two arguments are the "from" and "to" URL string. We need to
  // skip them, but we also require that there be an option to masquerade as
  // argv[0], so we increment the argument indexes by 1 rather than by 2.
  argc--;
  argv++;

  for (;;) {
    int opt = getopt_long(argc, (char *const *)argv, "", longopt, NULL);

    if (opt == -1) {
      break;
    }

    switch (opt) {
    case 'a':
      purge->allow_get = true;
      break;
    case 'h':
      purge->header     = TSstrdup(optarg);
      purge->header_len = strlen(purge->header);
      break;
    case 'i':
      purge->id = TSstrdup(optarg);
      break;
    case 's':
      purge->secret     = TSstrdup(optarg);
      purge->secret_len = strlen(purge->secret);
      break;
    case 'f':
      purge->state_file = make_state_path(optarg);
      break;
    }
  }

  if ((NULL == purge->secret) || (NULL == purge->state_file) || !purge->secret_len) {
    TSError("[%s] Unable to create remap instance, need at least a secret (--secret) and state (--state_file)", PLUGIN_NAME);
    delete_purge_instance(purge);
    return TS_ERROR;
  } else {
    if (!purge->id) {
      purge->id = TSstrdup(id);
    }
    init_purge_instance(purge);
    *ih = (void *)purge;
    return TS_SUCCESS;
  }
}

void
TSRemapDeleteInstance(void *ih)
{
  PurgeInstance *purge = (PurgeInstance *)ih;

  delete_purge_instance(purge);
}

TSRemapStatus
TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
{
  PurgeInstance *purge = (PurgeInstance *)ih;

  handle_purge(txnp, purge);
  return TSREMAP_NO_REMAP; // This plugin never rewrites anything.
}
