/** @file

  Transforms content using gzip, deflate or brotli

  @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 <cstring>
#include <zlib.h>

#include "ink_autoconf.h"

#if HAVE_BROTLI_ENCODE_H
#include <brotli/encode.h>
#endif

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

#include "debug_macros.h"
#include "misc.h"
#include "configuration.h"
#include "ts/remap.h"

using namespace std;
using namespace Gzip;

// FIXME: custom dictionaries would be nice. configurable/content-type?
// a GPRS device might benefit from a higher compression ratio, whereas a desktop w. high bandwith
// might be served better with little or no compression at all
// FIXME: look into compressing from the task thread pool
// FIXME: make normalizing accept encoding configurable

// from mod_deflate:
// ZLIB's compression algorithm uses a
// 0-9 based scale that GZIP does where '1' is 'Best speed'
// and '9' is 'Best compression'. Testing has proved level '6'
// to be about the best level to use in an HTTP Server.

const int ZLIB_COMPRESSION_LEVEL = 6;
const char *dictionary           = nullptr;
const char *TS_HTTP_VALUE_BROTLI = "br";
const int TS_HTTP_LEN_BROTLI     = 2;

// brotli compression quality 1-11. Testing proved level '6'
#if HAVE_BROTLI_ENCODE_H
const int BROTLI_COMPRESSION_LEVEL = 6;
const int BROTLI_LGW               = 16;
#endif

static const char *global_hidden_header_name = nullptr;

static TSMutex compress_config_mutex = TSMutexCreate();

// Current global configuration, and the previous one (for cleanup)
Configuration *cur_config  = nullptr;
Configuration *prev_config = nullptr;

static Data *
data_alloc(int compression_type, int compression_algorithms)
{
  Data *data;
  int err;

  data                         = static_cast<Data *>(TSmalloc(sizeof(Data)));
  data->downstream_vio         = nullptr;
  data->downstream_buffer      = nullptr;
  data->downstream_reader      = nullptr;
  data->downstream_length      = 0;
  data->state                  = transform_state_initialized;
  data->compression_type       = compression_type;
  data->compression_algorithms = compression_algorithms;
  data->zstrm.next_in          = Z_NULL;
  data->zstrm.avail_in         = 0;
  data->zstrm.total_in         = 0;
  data->zstrm.next_out         = Z_NULL;
  data->zstrm.avail_out        = 0;
  data->zstrm.total_out        = 0;
  data->zstrm.zalloc           = gzip_alloc;
  data->zstrm.zfree            = gzip_free;
  data->zstrm.opaque           = (voidpf) nullptr;
  data->zstrm.data_type        = Z_ASCII;

  int window_bits = WINDOW_BITS_GZIP;
  if (compression_type & COMPRESSION_TYPE_DEFLATE) {
    window_bits = WINDOW_BITS_DEFLATE;
  }

  err = deflateInit2(&data->zstrm, ZLIB_COMPRESSION_LEVEL, Z_DEFLATED, window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);

  if (err != Z_OK) {
    fatal("gzip-transform: ERROR: deflateInit (%d)!", err);
  }

  if (dictionary) {
    err = deflateSetDictionary(&data->zstrm, reinterpret_cast<const Bytef *>(dictionary), strlen(dictionary));
    if (err != Z_OK) {
      fatal("gzip-transform: ERROR: deflateSetDictionary (%d)!", err);
    }
  }
#if HAVE_BROTLI_ENCODE_H
  data->bstrm.br = nullptr;
  if (compression_type & COMPRESSION_TYPE_BROTLI) {
    debug("brotli compression. Create Brotli Encoder Instance.");
    data->bstrm.br = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
    if (!data->bstrm.br) {
      fatal("Brotli Encoder Instance Failed");
    }
    BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, BROTLI_COMPRESSION_LEVEL);
    BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, BROTLI_LGW);
    data->bstrm.next_in   = nullptr;
    data->bstrm.avail_in  = 0;
    data->bstrm.total_in  = 0;
    data->bstrm.next_out  = nullptr;
    data->bstrm.avail_out = 0;
    data->bstrm.total_out = 0;
  }
#endif
  return data;
}

static void
data_destroy(Data *data)
{
  TSReleaseAssert(data);

  // deflateEnd return value ignore is intentional
  // it would spew log on every client abort
  deflateEnd(&data->zstrm);

  if (data->downstream_buffer) {
    TSIOBufferDestroy(data->downstream_buffer);
  }

// brotlidestory
#if HAVE_BROTLI_ENCODE_H
  BrotliEncoderDestroyInstance(data->bstrm.br);
#endif

  TSfree(data);
}

static TSReturnCode
content_encoding_header(TSMBuffer bufp, TSMLoc hdr_loc, const int compression_type, int algorithm)
{
  TSReturnCode ret;
  TSMLoc ce_loc;
  const char *value = nullptr;
  int value_len     = 0;
  // Delete Content-Encoding if present???
  if (compression_type & COMPRESSION_TYPE_BROTLI && (algorithm & ALGORITHM_BROTLI)) {
    value     = TS_HTTP_VALUE_BROTLI;
    value_len = TS_HTTP_LEN_BROTLI;
  } else if (compression_type & COMPRESSION_TYPE_GZIP && (algorithm & ALGORITHM_GZIP)) {
    value     = TS_HTTP_VALUE_GZIP;
    value_len = TS_HTTP_LEN_GZIP;
  } else if (compression_type & COMPRESSION_TYPE_DEFLATE && (algorithm & ALGORITHM_DEFLATE)) {
    value     = TS_HTTP_VALUE_DEFLATE;
    value_len = TS_HTTP_LEN_DEFLATE;
  }

  if (value_len == 0) {
    error("no need to add Content-Encoding header");
    return TS_SUCCESS;
  }

  if ((ret = TSMimeHdrFieldCreateNamed(bufp, hdr_loc, TS_MIME_FIELD_CONTENT_ENCODING, TS_MIME_LEN_CONTENT_ENCODING, &ce_loc)) ==
      TS_SUCCESS) {
    ret = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, ce_loc, -1, value, value_len);
    if (ret == TS_SUCCESS) {
      ret = TSMimeHdrFieldAppend(bufp, hdr_loc, ce_loc);
    }
    TSHandleMLocRelease(bufp, hdr_loc, ce_loc);
  }

  if (ret != TS_SUCCESS) {
    error("cannot add the Content-Encoding header");
  }

  return ret;
}

static TSReturnCode
vary_header(TSMBuffer bufp, TSMLoc hdr_loc)
{
  TSReturnCode ret;
  TSMLoc ce_loc;

  ce_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_VARY, TS_MIME_LEN_VARY);
  if (ce_loc) {
    int idx, count, len;

    count = TSMimeHdrFieldValuesCount(bufp, hdr_loc, ce_loc);
    for (idx = 0; idx < count; idx++) {
      const char *value = TSMimeHdrFieldValueStringGet(bufp, hdr_loc, ce_loc, idx, &len);
      if (len && strncasecmp("Accept-Encoding", value, len) == 0) {
        // Bail, Vary: Accept-Encoding already sent from origin
        TSHandleMLocRelease(bufp, hdr_loc, ce_loc);
        return TS_SUCCESS;
      }
    }

    ret = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, ce_loc, -1, TS_MIME_FIELD_ACCEPT_ENCODING, TS_MIME_LEN_ACCEPT_ENCODING);
    TSHandleMLocRelease(bufp, hdr_loc, ce_loc);
  } else {
    if ((ret = TSMimeHdrFieldCreateNamed(bufp, hdr_loc, TS_MIME_FIELD_VARY, TS_MIME_LEN_VARY, &ce_loc)) == TS_SUCCESS) {
      if ((ret = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, ce_loc, -1, TS_MIME_FIELD_ACCEPT_ENCODING,
                                                 TS_MIME_LEN_ACCEPT_ENCODING)) == TS_SUCCESS) {
        ret = TSMimeHdrFieldAppend(bufp, hdr_loc, ce_loc);
      }

      TSHandleMLocRelease(bufp, hdr_loc, ce_loc);
    }
  }

  if (ret != TS_SUCCESS) {
    error("cannot add/update the Vary header");
  }

  return ret;
}

// FIXME: the etag alteration isn't proper. it should modify the value inside quotes
//       specify a very header..
static TSReturnCode
etag_header(TSMBuffer bufp, TSMLoc hdr_loc)
{
  TSReturnCode ret = TS_SUCCESS;
  TSMLoc ce_loc;

  ce_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_ETAG, TS_MIME_LEN_ETAG);

  if (ce_loc) {
    int strl;
    const char *strv = TSMimeHdrFieldValueStringGet(bufp, hdr_loc, ce_loc, -1, &strl);

    // do not alter weak etags.
    // FIXME: consider just making the etag weak for compressed content
    if (strl >= 2) {
      int changetag = 1;
      if ((strv[0] == 'w' || strv[0] == 'W') && strv[1] == '/') {
        changetag = 0;
      }
      if (changetag) {
        ret = TSMimeHdrFieldValueAppend(bufp, hdr_loc, ce_loc, 0, "-df", 3);
      }
    }
    TSHandleMLocRelease(bufp, hdr_loc, ce_loc);
  }

  if (ret != TS_SUCCESS) {
    error("cannot handle the %s header", TS_MIME_FIELD_ETAG);
  }

  return ret;
}

// FIXME: some things are potentially compressible. those responses
static void
compress_transform_init(TSCont contp, Data *data)
{
  // update the vary, content-encoding, and etag response headers
  // prepare the downstream for transforming

  TSVConn downstream_conn;
  TSMBuffer bufp;
  TSMLoc hdr_loc;

  data->state = transform_state_output;

  if (TSHttpTxnTransformRespGet(data->txn, &bufp, &hdr_loc) != TS_SUCCESS) {
    error("Error TSHttpTxnTransformRespGet");
    return;
  }

  if (content_encoding_header(bufp, hdr_loc, data->compression_type, data->compression_algorithms) == TS_SUCCESS &&
      vary_header(bufp, hdr_loc) == TS_SUCCESS && etag_header(bufp, hdr_loc) == TS_SUCCESS) {
    downstream_conn         = TSTransformOutputVConnGet(contp);
    data->downstream_buffer = TSIOBufferCreate();
    data->downstream_reader = TSIOBufferReaderAlloc(data->downstream_buffer);
    data->downstream_vio    = TSVConnWrite(downstream_conn, contp, data->downstream_reader, INT64_MAX);
  }

  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
}

static void
gzip_transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length)
{
  TSIOBufferBlock downstream_blkp;
  int64_t downstream_length;
  int err;
  data->zstrm.next_in  = (unsigned char *)upstream_buffer;
  data->zstrm.avail_in = upstream_length;

  while (data->zstrm.avail_in > 0) {
    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, &downstream_length);

    data->zstrm.next_out  = reinterpret_cast<unsigned char *>(downstream_buffer);
    data->zstrm.avail_out = downstream_length;

    if (!data->hc->flush()) {
      err = deflate(&data->zstrm, Z_NO_FLUSH);
    } else {
      err = deflate(&data->zstrm, Z_SYNC_FLUSH);
    }

    if (err != Z_OK) {
      warning("deflate() call failed: %d", err);
    }

    if (downstream_length > data->zstrm.avail_out) {
      TSIOBufferProduce(data->downstream_buffer, downstream_length - data->zstrm.avail_out);
      data->downstream_length += (downstream_length - data->zstrm.avail_out);
    }

    if (data->zstrm.avail_out > 0) {
      if (data->zstrm.avail_in != 0) {
        error("gzip-transform: avail_in is (%d): should be 0", data->zstrm.avail_in);
      }
    }
  }
}

#if HAVE_BROTLI_ENCODE_H
static bool
brotli_compress_operation(Data *data, const char *upstream_buffer, int64_t upstream_length, BrotliEncoderOperation op)
{
  TSIOBufferBlock downstream_blkp;
  int64_t downstream_length;

  data->bstrm.next_in  = (uint8_t *)upstream_buffer;
  data->bstrm.avail_in = upstream_length;

  bool ok = true;
  while (ok) {
    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, &downstream_length);

    data->bstrm.next_out  = reinterpret_cast<unsigned char *>(downstream_buffer);
    data->bstrm.avail_out = downstream_length;
    data->bstrm.total_out = 0;

    ok =
      !!BrotliEncoderCompressStream(data->bstrm.br, op, &data->bstrm.avail_in, &const_cast<const uint8_t *&>(data->bstrm.next_in),
                                    &data->bstrm.avail_out, &data->bstrm.next_out, &data->bstrm.total_out);

    if (!ok) {
      error("BrotliEncoderCompressStream(%d) call failed", op);
      return false;
    }

    TSIOBufferProduce(data->downstream_buffer, downstream_length - data->bstrm.avail_out);
    data->downstream_length += (downstream_length - data->bstrm.avail_out);
    if (data->bstrm.avail_in || BrotliEncoderHasMoreOutput(data->bstrm.br)) {
      continue;
    }

    break;
  }

  return ok;
}

static void
brotli_transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length)
{
  bool ok = brotli_compress_operation(data, upstream_buffer, upstream_length, BROTLI_OPERATION_PROCESS);
  if (!ok) {
    error("BrotliEncoderCompressStream(PROCESS) call failed");
    return;
  }

  data->bstrm.total_in += upstream_length;

  if (!data->hc->flush()) {
    return;
  }

  ok = brotli_compress_operation(data, nullptr, 0, BROTLI_OPERATION_FLUSH);
  if (!ok) {
    error("BrotliEncoderCompressStream(FLUSH) call failed");
    return;
  }
}
#endif

static void
compress_transform_one(Data *data, TSIOBufferReader upstream_reader, int amount)
{
  TSIOBufferBlock downstream_blkp;
  int64_t upstream_length;
  while (amount > 0) {
    downstream_blkp = TSIOBufferReaderStart(upstream_reader);
    if (!downstream_blkp) {
      error("couldn't get from IOBufferBlock");
      return;
    }

    const char *upstream_buffer = TSIOBufferBlockReadStart(downstream_blkp, upstream_reader, &upstream_length);
    if (!upstream_buffer) {
      error("couldn't get from TSIOBufferBlockReadStart");
      return;
    }

    if (upstream_length > amount) {
      upstream_length = amount;
    }

#if HAVE_BROTLI_ENCODE_H
    if (data->compression_type & COMPRESSION_TYPE_BROTLI && (data->compression_algorithms & ALGORITHM_BROTLI)) {
      brotli_transform_one(data, upstream_buffer, upstream_length);
    } else
#endif
      if ((data->compression_type & (COMPRESSION_TYPE_GZIP | COMPRESSION_TYPE_DEFLATE)) &&
          (data->compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) {
      gzip_transform_one(data, upstream_buffer, upstream_length);
    } else {
      warning("No compression supported. Shouldn't come here.");
    }

    TSIOBufferReaderConsume(upstream_reader, upstream_length);
    amount -= upstream_length;
  }
}

static void
gzip_transform_finish(Data *data)
{
  if (data->state == transform_state_output) {
    TSIOBufferBlock downstream_blkp;
    int64_t downstream_length;

    data->state = transform_state_finished;

    for (;;) {
      downstream_blkp = TSIOBufferStart(data->downstream_buffer);

      char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, &downstream_length);
      data->zstrm.next_out    = reinterpret_cast<unsigned char *>(downstream_buffer);
      data->zstrm.avail_out   = downstream_length;

      int err = deflate(&data->zstrm, Z_FINISH);

      if (downstream_length > static_cast<int64_t>(data->zstrm.avail_out)) {
        TSIOBufferProduce(data->downstream_buffer, downstream_length - data->zstrm.avail_out);
        data->downstream_length += (downstream_length - data->zstrm.avail_out);
      }

      if (err == Z_OK) { /* some more data to encode */
        continue;
      }

      if (err != Z_STREAM_END) {
        warning("deflate should report Z_STREAM_END");
      }
      break;
    }

    if (data->downstream_length != static_cast<int64_t>(data->zstrm.total_out)) {
      error("gzip-transform: output lengths don't match (%d, %ld)", data->downstream_length, data->zstrm.total_out);
    }

    debug("gzip-transform: Finished gzip");
    log_compression_ratio(data->zstrm.total_in, data->downstream_length);
  }
}

#if HAVE_BROTLI_ENCODE_H
static void
brotli_transform_finish(Data *data)
{
  if (data->state != transform_state_output) {
    return;
  }

  data->state = transform_state_finished;

  bool ok = brotli_compress_operation(data, nullptr, 0, BROTLI_OPERATION_FINISH);
  if (!ok) {
    error("BrotliEncoderCompressStream(PROCESS) call failed");
    return;
  }

  if (data->downstream_length != static_cast<int64_t>(data->bstrm.total_out)) {
    error("brotli-transform: output lengths don't match (%d, %ld)", data->downstream_length, data->bstrm.total_out);
  }

  debug("brotli-transform: Finished brotli");
  log_compression_ratio(data->bstrm.total_in, data->downstream_length);
}
#endif

static void
compress_transform_finish(Data *data)
{
#if HAVE_BROTLI_ENCODE_H
  if (data->compression_type & COMPRESSION_TYPE_BROTLI && data->compression_algorithms & ALGORITHM_BROTLI) {
    brotli_transform_finish(data);
    debug("compress_transform_finish: brotli compression finish");
  } else
#endif
    if ((data->compression_type & (COMPRESSION_TYPE_GZIP | COMPRESSION_TYPE_DEFLATE)) &&
        (data->compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) {
    gzip_transform_finish(data);
    debug("compress_transform_finish: gzip compression finish");
  } else {
    error("No Compression matched, shouldn't come here");
  }
}

static void
compress_transform_do(TSCont contp)
{
  TSVIO upstream_vio;
  Data *data;
  int64_t upstream_todo;
  int64_t downstream_bytes_written;

  data = static_cast<Data *>(TSContDataGet(contp));
  if (data->state == transform_state_initialized) {
    compress_transform_init(contp, data);
  }

  upstream_vio             = TSVConnWriteVIOGet(contp);
  downstream_bytes_written = data->downstream_length;

  if (!TSVIOBufferGet(upstream_vio)) {
    compress_transform_finish(data);

    TSVIONBytesSet(data->downstream_vio, data->downstream_length);

    if (data->downstream_length > downstream_bytes_written) {
      TSVIOReenable(data->downstream_vio);
    }
    return;
  }

  upstream_todo = TSVIONTodoGet(upstream_vio);

  if (upstream_todo > 0) {
    int64_t upstream_avail = TSIOBufferReaderAvail(TSVIOReaderGet(upstream_vio));

    if (upstream_todo > upstream_avail) {
      upstream_todo = upstream_avail;
    }

    if (upstream_todo > 0) {
      compress_transform_one(data, TSVIOReaderGet(upstream_vio), upstream_todo);
      TSVIONDoneSet(upstream_vio, TSVIONDoneGet(upstream_vio) + upstream_todo);
    }
  }

  if (TSVIONTodoGet(upstream_vio) > 0) {
    if (upstream_todo > 0) {
      if (data->downstream_length > downstream_bytes_written) {
        TSVIOReenable(data->downstream_vio);
      }
      TSContCall(TSVIOContGet(upstream_vio), TS_EVENT_VCONN_WRITE_READY, upstream_vio);
    }
  } else {
    compress_transform_finish(data);
    TSVIONBytesSet(data->downstream_vio, data->downstream_length);

    if (data->downstream_length > downstream_bytes_written) {
      TSVIOReenable(data->downstream_vio);
    }

    TSContCall(TSVIOContGet(upstream_vio), TS_EVENT_VCONN_WRITE_COMPLETE, upstream_vio);
  }
}

static int
compress_transform(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
  if (TSVConnClosedGet(contp)) {
    data_destroy(static_cast<Data *>(TSContDataGet(contp)));
    TSContDestroy(contp);
    return 0;
  } else {
    switch (event) {
    case TS_EVENT_ERROR: {
      debug("compress_transform: TS_EVENT_ERROR starts");
      TSVIO upstream_vio = TSVConnWriteVIOGet(contp);
      TSContCall(TSVIOContGet(upstream_vio), TS_EVENT_ERROR, upstream_vio);
    } break;
    case TS_EVENT_VCONN_WRITE_COMPLETE:
      TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1);
      break;
    case TS_EVENT_VCONN_WRITE_READY:
      compress_transform_do(contp);
      break;
    case TS_EVENT_IMMEDIATE:
      compress_transform_do(contp);
      break;
    default:
      warning("unknown event [%d]", event);
      compress_transform_do(contp);
      break;
    }
  }

  return 0;
}

static int
transformable(TSHttpTxn txnp, bool server, HostConfiguration *host_configuration, int *compress_type, int *algorithms)
{
  /* Server response header */
  TSMBuffer bufp;
  TSMLoc hdr_loc;
  TSMLoc field_loc;

  /* Client request header */
  TSMBuffer cbuf;
  TSMLoc chdr;
  TSMLoc cfield, rfield;

  const char *value;
  int len;
  TSHttpStatus resp_status;

  if (server) {
    if (TS_SUCCESS != TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc)) {
      return 0;
    }
  } else {
    if (TS_SUCCESS != TSHttpTxnCachedRespGet(txnp, &bufp, &hdr_loc)) {
      return 0;
    }
  }

  resp_status = TSHttpHdrStatusGet(bufp, hdr_loc);

  // NOTE: error responses can mess up plugins like the escalate.so plugin,
  // and possibly the escalation feature of parent.config. See #2913.
  if (!host_configuration->is_status_code_compressible(resp_status)) {
    info("http response status [%d] is not compressible", resp_status);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  // We got a server response but it was a 304
  // we need to update our data to come from cache instead of
  // the 304 response which does not need to include all headers
  if ((server) && (resp_status == TS_HTTP_STATUS_NOT_MODIFIED)) {
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    if (TS_SUCCESS != TSHttpTxnCachedRespGet(txnp, &bufp, &hdr_loc)) {
      return 0;
    }
  }

  if (TS_SUCCESS != TSHttpTxnClientReqGet(txnp, &cbuf, &chdr)) {
    info("cound not get client request");
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  // check if Range Requests are cacheable
  bool range_request = host_configuration->range_request();
  rfield             = TSMimeHdrFieldFind(cbuf, chdr, TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE);
  if (rfield != TS_NULL_MLOC && !range_request) {
    debug("Range header found in the request and range_request is configured as false, not compressible");
    TSHandleMLocRelease(cbuf, chdr, rfield);
    TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  // the only compressible method is currently GET.
  int method_length;
  const char *method = TSHttpHdrMethodGet(cbuf, chdr, &method_length);

  if (!((method_length == TS_HTTP_LEN_GET && memcmp(method, TS_HTTP_METHOD_GET, TS_HTTP_LEN_GET) == 0) ||
        (method_length == TS_HTTP_LEN_POST && memcmp(method, TS_HTTP_METHOD_POST, TS_HTTP_LEN_POST) == 0))) {
    debug("method is not GET or POST, not compressible");
    TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  *algorithms = host_configuration->compression_algorithms();
  cfield      = TSMimeHdrFieldFind(cbuf, chdr, TS_MIME_FIELD_ACCEPT_ENCODING, TS_MIME_LEN_ACCEPT_ENCODING);
  if (cfield != TS_NULL_MLOC) {
    int compression_acceptable = 0;
    int nvalues                = TSMimeHdrFieldValuesCount(cbuf, chdr, cfield);
    for (int i = 0; i < nvalues; i++) {
      value = TSMimeHdrFieldValueStringGet(cbuf, chdr, cfield, i, &len);
      if (!value) {
        continue;
      }

      if (strncasecmp(value, "br", sizeof("br") - 1) == 0) {
        if (*algorithms & ALGORITHM_BROTLI) {
          compression_acceptable = 1;
        }
        *compress_type |= COMPRESSION_TYPE_BROTLI;
      } else if (strncasecmp(value, "deflate", sizeof("deflate") - 1) == 0) {
        if (*algorithms & ALGORITHM_DEFLATE) {
          compression_acceptable = 1;
        }
        *compress_type |= COMPRESSION_TYPE_DEFLATE;
      } else if (strncasecmp(value, "gzip", sizeof("gzip") - 1) == 0) {
        if (*algorithms & ALGORITHM_GZIP) {
          compression_acceptable = 1;
        }
        *compress_type |= COMPRESSION_TYPE_GZIP;
      }
    }

    TSHandleMLocRelease(cbuf, chdr, cfield);
    TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);

    if (!compression_acceptable) {
      info("no acceptable encoding match found in request header, not compressible");
      TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
      return 0;
    }
  } else {
    info("no acceptable encoding found in request header, not compressible");
    TSHandleMLocRelease(cbuf, chdr, cfield);
    TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  /* If there already exists a content encoding then we don't want
     to do anything. */
  field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_CONTENT_ENCODING, -1);
  if (field_loc) {
    info("response is already content encoded, not compressible");
    TSHandleMLocRelease(bufp, hdr_loc, field_loc);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH);
  if (field_loc != TS_NULL_MLOC) {
    unsigned int hdr_value = TSMimeHdrFieldValueUintGet(bufp, hdr_loc, field_loc, -1);
    TSHandleMLocRelease(bufp, hdr_loc, field_loc);
    if (hdr_value == 0) {
      info("response is 0-length, not compressible");
      return 0;
    }

    if (hdr_value < host_configuration->minimum_content_length()) {
      info("response is is smaller than minimum content length, not compressing");
      return 0;
    }
  }

  /* We only want to do gzip compression on documents that have a
     content type of "text/" or "application/x-javascript". */
  field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_CONTENT_TYPE, -1);
  if (!field_loc) {
    info("no content type header found, not compressible");
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    return 0;
  }

  value = TSMimeHdrFieldValueStringGet(bufp, hdr_loc, field_loc, -1, &len);

  int rv = host_configuration->is_content_type_compressible(value, len);

  if (!rv) {
    info("content-type [%.*s] not compressible", len, value);
  }

  TSHandleMLocRelease(bufp, hdr_loc, field_loc);
  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);

  return rv;
}

static void
compress_transform_add(TSHttpTxn txnp, HostConfiguration *hc, int compress_type, int algorithms)
{
  TSVConn connp;
  Data *data;

  TSHttpTxnUntransformedRespCache(txnp, 1);

  if (!hc->cache()) {
    debug("TransformedRespCache  not enabled");
    TSHttpTxnTransformedRespCache(txnp, 0);
  } else {
    debug("TransformedRespCache  enabled");
    TSHttpTxnUntransformedRespCache(txnp, 0);
    TSHttpTxnTransformedRespCache(txnp, 1);
  }

  connp     = TSTransformCreate(compress_transform, txnp);
  data      = data_alloc(compress_type, algorithms);
  data->txn = txnp;
  data->hc  = hc;

  TSContDataSet(connp, data);
  TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
}

HostConfiguration *
find_host_configuration(TSHttpTxn /* txnp ATS_UNUSED */, TSMBuffer bufp, TSMLoc locp, Configuration *config)
{
  TSMLoc fieldp    = TSMimeHdrFieldFind(bufp, locp, TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST);
  int strl         = 0;
  const char *strv = nullptr;
  HostConfiguration *host_configuration;

  if (fieldp) {
    strv = TSMimeHdrFieldValueStringGet(bufp, locp, fieldp, -1, &strl);
    TSHandleMLocRelease(bufp, locp, fieldp);
  }
  if (config == nullptr) {
    host_configuration = cur_config->find(strv, strl);
  } else {
    host_configuration = config->find(strv, strl);
  }
  return host_configuration;
}

static int
transform_plugin(TSCont contp, TSEvent event, void *edata)
{
  TSHttpTxn txnp        = static_cast<TSHttpTxn>(edata);
  int compress_type     = COMPRESSION_TYPE_DEFAULT;
  int algorithms        = ALGORITHM_DEFAULT;
  HostConfiguration *hc = static_cast<HostConfiguration *>(TSContDataGet(contp));

  switch (event) {
  case TS_EVENT_HTTP_READ_RESPONSE_HDR:
    // os: the accept encoding header needs to be restored..
    // otherwise the next request won't get a cache hit on this
    if (hc != nullptr) {
      info("reading response headers");
      if (hc->remove_accept_encoding()) {
        TSMBuffer req_buf;
        TSMLoc req_loc;

        if (TSHttpTxnServerReqGet(txnp, &req_buf, &req_loc) == TS_SUCCESS) {
          restore_accept_encoding(txnp, req_buf, req_loc, global_hidden_header_name);
          TSHandleMLocRelease(req_buf, TS_NULL_MLOC, req_loc);
        }
      }

      if (transformable(txnp, true, hc, &compress_type, &algorithms)) {
        compress_transform_add(txnp, hc, compress_type, algorithms);
      }
    }
    break;

  case TS_EVENT_HTTP_SEND_REQUEST_HDR:
    if (hc != nullptr) {
      info("preparing send request headers");
      if (hc->remove_accept_encoding()) {
        TSMBuffer req_buf;
        TSMLoc req_loc;

        if (TSHttpTxnServerReqGet(txnp, &req_buf, &req_loc) == TS_SUCCESS) {
          hide_accept_encoding(txnp, req_buf, req_loc, global_hidden_header_name);
          TSHandleMLocRelease(req_buf, TS_NULL_MLOC, req_loc);
        }
      }
      TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, contp);
    }
    break;

  case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: {
    int obj_status;

    if (TS_ERROR != TSHttpTxnCacheLookupStatusGet(txnp, &obj_status) && (TS_CACHE_LOOKUP_HIT_FRESH == obj_status)) {
      if (hc != nullptr) {
        info("handling compression of cached object");
        if (transformable(txnp, false, hc, &compress_type, &algorithms)) {
          compress_transform_add(txnp, hc, compress_type, algorithms);
        }
      }
    } else {
      // Prepare for going to origin
      info("preparing to go to origin");
      TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_REQUEST_HDR_HOOK, contp);
    }
  } break;

  case TS_EVENT_HTTP_TXN_CLOSE:
    // Release the ocnif lease, and destroy this continuation
    TSContDestroy(contp);
    break;

  default:
    fatal("compress transform unknown event");
  }

  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);

  return 0;
}

/**
 * This handles a compress request
 * 1. Reads the client request header
 * 2. For global plugin, get host configuration from global config
 *    For remap plugin, get host configuration from configs populated through remap
 * 3. Check for Accept encoding
 * 4. Schedules TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK and TS_HTTP_TXN_CLOSE_HOOK for
 *    further processing
 */
static void
handle_request(TSHttpTxn txnp, Configuration *config)
{
  TSMBuffer req_buf;
  TSMLoc req_loc;
  HostConfiguration *hc;

  if (TSHttpTxnClientReqGet(txnp, &req_buf, &req_loc) == TS_SUCCESS) {
    if (config == nullptr) {
      hc = find_host_configuration(txnp, req_buf, req_loc, nullptr);
    } else {
      hc = find_host_configuration(txnp, req_buf, req_loc, config);
    }
    bool allowed = false;

    if (hc->enabled()) {
      if (hc->has_allows()) {
        int url_len;
        char *url = TSHttpTxnEffectiveUrlStringGet(txnp, &url_len);
        allowed   = hc->is_url_allowed(url, url_len);
        TSfree(url);
      } else {
        allowed = true;
      }
    }
    if (allowed) {
      TSCont transform_contp = TSContCreate(transform_plugin, nullptr);

      TSContDataSet(transform_contp, (void *)hc);

      info("Kicking off compress plugin for request");
      normalize_accept_encoding(txnp, req_buf, req_loc);
      TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, transform_contp);
      TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, transform_contp); // To release the config
    }
    TSHandleMLocRelease(req_buf, TS_NULL_MLOC, req_loc);
  }
}

static int
transform_global_plugin(TSCont /* contp ATS_UNUSED */, TSEvent event, void *edata)
{
  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);

  switch (event) {
  case TS_EVENT_HTTP_READ_REQUEST_HDR:
    // Handle compress request and use the global configs
    handle_request(txnp, nullptr);
    break;

  default:
    fatal("compress global transform unknown event");
  }

  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);

  return 0;
}

static void
load_global_configuration(TSCont contp)
{
  const char *path         = static_cast<const char *>(TSContDataGet(contp));
  Configuration *newconfig = Configuration::Parse(path);
  Configuration *oldconfig = __sync_lock_test_and_set(&cur_config, newconfig);

  debug("config swapped, old config %p", oldconfig);

  // need a mutex for when there are multiple reloads going on
  TSMutexLock(compress_config_mutex);
  if (prev_config) {
    debug("deleting previous configuration container, %p", prev_config);
    delete prev_config;
  }
  prev_config = oldconfig;
  TSMutexUnlock(compress_config_mutex);
}

static int
management_update(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
  TSReleaseAssert(event == TS_EVENT_MGMT_UPDATE);
  info("management update event received");
  load_global_configuration(contp);

  return 0;
}

void
TSPluginInit(int argc, const char *argv[])
{
  const char *config_path = nullptr;

  if (argc > 2) {
    fatal("the compress plugin does not accept more than 1 plugin argument");
  } else {
    config_path = TSstrdup(2 == argc ? argv[1] : "");
  }

  if (!register_plugin()) {
    fatal("the compress plugin failed to register");
  }

  info("TSPluginInit %s", argv[0]);

  if (!global_hidden_header_name) {
    global_hidden_header_name = init_hidden_header_name();
  }

  TSCont management_contp = TSContCreate(management_update, nullptr);

  // Make sure the global configuration is properly loaded and reloaded on changes
  TSContDataSet(management_contp, (void *)config_path);
  TSMgmtUpdateRegister(management_contp, TAG);
  load_global_configuration(management_contp);

  // Setup the global hook, main entry point for kicking off the plugin
  TSCont transform_global_contp = TSContCreate(transform_global_plugin, nullptr);

  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, transform_global_contp);
  info("loaded");
}

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

  if (api_info->tsremap_version < TSREMAP_VERSION) {
    snprintf(errbuf, errbuf_size, "[TSRemapInit] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16,
             (api_info->tsremap_version & 0xffff));
    return TS_ERROR;
  }

  info("The compress plugin is successfully initialized");
  return TS_SUCCESS;
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **instance, char *errbuf, int errbuf_size)
{
  info("Instantiating a new compress plugin remap rule");
  info("Reading config from file = %s", argv[2]);

  const char *config_path = nullptr;

  if (argc > 4) {
    fatal("The compress plugin does not accept more than one plugin argument");
  } else {
    config_path = TSstrdup(3 == argc ? argv[2] : "");
  }
  if (!global_hidden_header_name) {
    global_hidden_header_name = init_hidden_header_name();
  }

  Configuration *config = Configuration::Parse(config_path);
  *instance             = config;

  free((void *)config_path);
  info("Configuration loaded");
  return TS_SUCCESS;
}

void
TSRemapDeleteInstance(void *instance)
{
  debug("Cleanup configs read from remap");
  auto c = static_cast<Configuration *>(instance);
  delete c;
}

TSRemapStatus
TSRemapDoRemap(void *instance, TSHttpTxn txnp, TSRemapRequestInfo *rri)
{
  if (nullptr == instance) {
    info("No Rules configured, falling back to default");
  } else {
    info("Remap Rules configured for compress");
    Configuration *config = static_cast<Configuration *>(instance);
    // Handle compress request and use the configs populated from remap instance
    handle_request(txnp, config);
  }
  return TSREMAP_NO_REMAP;
}
