/** @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 "ink_autoconf.h"
#include "configuration.h"
#include <fstream>
#include <algorithm>
#include <vector>
#include <fnmatch.h>

#include "debug_macros.h"

namespace Gzip
{
using namespace std;

void
ltrim_if(string &s, int (*fp)(int))
{
  for (size_t i = 0; i < s.size();) {
    if (fp(s[i])) {
      s.erase(i, 1);
    } else {
      break;
    }
  }
}

void
rtrim_if(string &s, int (*fp)(int))
{
  for (ssize_t i = static_cast<ssize_t>(s.size()) - 1; i >= 0; i--) {
    if (fp(s[i])) {
      s.erase(i, 1);
    } else {
      break;
    }
  }
}

void
trim_if(string &s, int (*fp)(int))
{
  ltrim_if(s, fp);
  rtrim_if(s, fp);
}

string
extractFirstToken(string &s, int (*fp)(int))
{
  int startTok{-1}, endTok{-1}, idx{0};

  for (;; ++idx) {
    if (idx == int(s.length())) {
      if (endTok < 0) {
        endTok = idx;
      }
      break;
    } else if (fp(s[idx])) {
      if ((startTok >= 0) and (endTok < 0)) {
        endTok = idx;
      }
    } else if (endTok > 0) {
      break;
    } else if (startTok < 0) {
      startTok = idx;
    }
  }

  string tmp;
  if (startTok >= 0) {
    tmp = string(s, startTok, endTok - startTok);
  }

  if (idx > 0) {
    s = string(s, idx, s.length() - idx);
  }

  return tmp;
}

enum ParserState {
  kParseStart,
  kParseCompressibleContentType,
  kParseRemoveAcceptEncoding,
  kParseEnable,
  kParseCache,
  kParseRangeRequest,
  kParseFlush,
  kParseAllow,
  kParseMinimumContentLength
};

void
Configuration::add_host_configuration(HostConfiguration *hc)
{
  host_configurations_.push_back(hc);
}

void
HostConfiguration::update_defaults()
{
  // maintain backwards compatibility/usability out of the box
  if (compressible_status_codes_.empty()) {
    compressible_status_codes_ = {TS_HTTP_STATUS_OK, TS_HTTP_STATUS_PARTIAL_CONTENT, TS_HTTP_STATUS_NOT_MODIFIED};
  }
}

void
HostConfiguration::add_allow(const std::string &allow)
{
  allows_.push_back(allow);
}

void
HostConfiguration::add_compressible_content_type(const std::string &content_type)
{
  compressible_content_types_.push_back(content_type);
}

HostConfiguration *
Configuration::find(const char *host, int host_length)
{
  HostConfiguration *host_configuration = host_configurations_[0];

  if (host && host_length > 0 && host_configurations_.size() > 1) {
    std::string shost(host, host_length);

    // ToDo: Maybe use std::find() here somehow?
    for (HostContainer::iterator it = host_configurations_.begin() + 1; it != host_configurations_.end(); ++it) {
      if ((*it)->host() == shost) {
        host_configuration = *it;
        break;
      }
    }
  }

  return host_configuration;
}

bool
HostConfiguration::is_url_allowed(const char *url, int url_len)
{
  string surl(url, url_len);
  if (has_allows()) {
    for (StringContainer::iterator allow_it = allows_.begin(); allow_it != allows_.end(); ++allow_it) {
      const char *match_string = allow_it->c_str();
      bool exclude             = match_string[0] == '!';
      if (exclude) {
        ++match_string; // skip !
      }
      if (fnmatch(match_string, surl.c_str(), 0) == 0) {
        info("url [%s] %s for compression, matched allow pattern [%s]", surl.c_str(), exclude ? "disabled" : "enabled",
             allow_it->c_str());
        return !exclude;
      }
    }
    info("url [%s] disabled for compression, did not match any allows pattern", surl.c_str());
    return false;
  }
  info("url [%s] enabled for compression, did not match any pattern", surl.c_str());
  return true;
}

bool
HostConfiguration::is_status_code_compressible(const TSHttpStatus status_code) const
{
  std::set<TSHttpStatus>::const_iterator it = compressible_status_codes_.find(status_code);

  return it != compressible_status_codes_.end();
}

bool
HostConfiguration::is_content_type_compressible(const char *content_type, int content_type_length)
{
  string scontent_type(content_type, content_type_length);
  bool is_match = false;

  for (StringContainer::iterator it = compressible_content_types_.begin(); it != compressible_content_types_.end(); ++it) {
    const char *match_string = it->c_str();
    if (match_string == nullptr) {
      continue;
    }
    bool exclude = match_string[0] == '!';

    if (exclude) {
      ++match_string; // skip '!'
    }
    if (fnmatch(match_string, scontent_type.c_str(), 0) == 0) {
      info("compressible content type [%s], matched on pattern [%s]", scontent_type.c_str(), it->c_str());
      is_match = !exclude;
    }
  }

  return is_match;
}

int
isCommaOrSpace(int ch)
{
  return (ch == ',') or isspace(ch);
}

void
HostConfiguration::add_compression_algorithms(string &line)
{
  compression_algorithms_ = ALGORITHM_DEFAULT; // remove the default gzip.
  for (;;) {
    string token = extractFirstToken(line, isCommaOrSpace);
    if (token.empty()) {
      break;
    } else if (token == "br") {
#ifdef HAVE_BROTLI_ENCODE_H
      compression_algorithms_ |= ALGORITHM_BROTLI;
#else
      error("supported-algorithms: brotli support not compiled in.");
#endif
    } else if (token == "gzip") {
      compression_algorithms_ |= ALGORITHM_GZIP;
    } else if (token == "deflate") {
      compression_algorithms_ |= ALGORITHM_DEFLATE;
    } else {
      error("Unknown compression type. Supported compression-algorithms <br,gzip,deflate>.");
    }
  }
}

void
HostConfiguration::add_compressible_status_codes(string &line)
{
  for (;;) {
    string token = extractFirstToken(line, isCommaOrSpace);
    if (token.empty()) {
      break;
    }

    uint status_code = strtoul(token.c_str(), nullptr, 10);
    if (status_code == 0) {
      error("Invalid status code %s", token.c_str());
      continue;
    }

    compressible_status_codes_.insert(static_cast<TSHttpStatus>(status_code));
  }
}

int
HostConfiguration::compression_algorithms()
{
  return compression_algorithms_;
}

Configuration *
Configuration::Parse(const char *path)
{
  string pathstring(path);

  // If we have a path and it's not an absolute path, make it relative to the
  // configuration directory.
  if (!pathstring.empty() && pathstring[0] != '/') {
    pathstring.assign(TSConfigDirGet());
    pathstring.append("/");
    pathstring.append(path);
  }

  trim_if(pathstring, isspace);

  Configuration *c                              = new Configuration();
  HostConfiguration *current_host_configuration = new HostConfiguration("");

  c->add_host_configuration(current_host_configuration);

  if (pathstring.empty()) {
    return c;
  }

  path = pathstring.c_str();
  info("Parsing file \"%s\"", path);
  std::ifstream f;

  size_t lineno = 0;

  f.open(path, std::ios::in);

  if (!f.is_open()) {
    warning("could not open file [%s], skip", path);
    return c;
  }

  enum ParserState state = kParseStart;

  while (!f.eof()) {
    std::string line;
    getline(f, line);
    ++lineno;

    trim_if(line, isspace);
    if (line.empty()) {
      continue;
    }

    for (;;) {
      string token = extractFirstToken(line, isspace);

      if (token.empty()) {
        break;
      }

      // once a comment is encountered, we are done processing the line
      if (token[0] == '#') {
        break;
      }

      switch (state) {
      case kParseStart:
        if ((token[0] == '[') && (token[token.size() - 1] == ']')) {
          std::string current_host = token.substr(1, token.size() - 2);

          // Makes sure that any default settings are properly set, when not explicitly set via configs
          current_host_configuration->update_defaults();
          current_host_configuration = new HostConfiguration(current_host);
          c->add_host_configuration(current_host_configuration);
        } else if (token == "compressible-content-type") {
          state = kParseCompressibleContentType;
        } else if (token == "remove-accept-encoding") {
          state = kParseRemoveAcceptEncoding;
        } else if (token == "enabled") {
          state = kParseEnable;
        } else if (token == "cache") {
          state = kParseCache;
        } else if (token == "range-request") {
          state = kParseRangeRequest;
        } else if (token == "flush") {
          state = kParseFlush;
        } else if (token == "supported-algorithms") {
          current_host_configuration->add_compression_algorithms(line);
          state = kParseStart;
        } else if (token == "allow") {
          state = kParseAllow;
        } else if (token == "compressible-status-code") {
          current_host_configuration->add_compressible_status_codes(line);
          state = kParseStart;
        } else if (token == "minimum-content-length") {
          state = kParseMinimumContentLength;
        } else {
          warning("failed to interpret \"%s\" at line %zu", token.c_str(), lineno);
        }
        break;
      case kParseCompressibleContentType:
        current_host_configuration->add_compressible_content_type(token);
        state = kParseStart;
        break;
      case kParseRemoveAcceptEncoding:
        current_host_configuration->set_remove_accept_encoding(token == "true");
        state = kParseStart;
        break;
      case kParseEnable:
        current_host_configuration->set_enabled(token == "true");
        state = kParseStart;
        break;
      case kParseCache:
        current_host_configuration->set_cache(token == "true");
        state = kParseStart;
        break;
      case kParseRangeRequest:
        current_host_configuration->set_range_request(token == "true");
        state = kParseStart;
        break;
      case kParseFlush:
        current_host_configuration->set_flush(token == "true");
        state = kParseStart;
        break;
      case kParseAllow:
        current_host_configuration->add_allow(token);
        state = kParseStart;
        break;
      case kParseMinimumContentLength:
        current_host_configuration->set_minimum_content_length(strtoul(token.c_str(), nullptr, 10));
        state = kParseStart;
        break;
      }
    }
  }

  // Update the defaults for the last host configuration too, if needed.
  current_host_configuration->update_defaults();

  if (state != kParseStart) {
    warning("the parser state indicates that data was expected when it reached the end of the file (%d)", state);
  }

  return c;
} // Configuration::Parse
} // namespace Gzip
