/** @file

  A brief file description

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

/*****************************************************************************
 *
 *  CacheControl.cc - Implementation to Cache Control systtem
 *
 *
 ****************************************************************************/

#include <sys/types.h>

#include "tscore/ink_config.h"
#include "CacheControl.h"
#include "ControlMatcher.h"
#include "Main.h"
#include "P_EventSystem.h"
#include "ProxyConfig.h"
#include "HTTP.h"
#include "HttpConfig.h"
#include "P_Cache.h"
#include "tscore/Regex.h"

static const char modulePrefix[] = "[CacheControl]";

#define TWEAK_CACHE_RESPONSES_TO_COOKIES "cache-responses-to-cookies"

static const char *CC_directive_str[CC_NUM_TYPES] = {
  "INVALID",
  "REVALIDATE_AFTER",
  "NEVER_CACHE",
  "STANDARD_CACHE",
  "IGNORE_NO_CACHE",
  "IGNORE_CLIENT_NO_CACHE",
  "IGNORE_SERVER_NO_CACHE",
  "PIN_IN_CACHE",
  "TTL_IN_CACHE"
  // "CACHE_AUTH_CONTENT"
};

typedef ControlMatcher<CacheControlRecord, CacheControlResult> CC_table;

// Global Ptrs
static Ptr<ProxyMutex> reconfig_mutex;
CC_table *CacheControlTable = nullptr;

void
CC_delete_table()
{
  delete CacheControlTable;
}

// struct CC_FreerContinuation
// Continuation to free old cache control lists after
//  a timeout
//
struct CC_FreerContinuation;
using CC_FreerContHandler = int (CC_FreerContinuation::*)(int, void *);
struct CC_FreerContinuation : public Continuation {
  CC_table *p;
  int
  freeEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
  {
    Debug("cache_control", "Deleting old table");
    delete p;
    delete this;
    return EVENT_DONE;
  }
  CC_FreerContinuation(CC_table *ap) : Continuation(nullptr), p(ap)
  {
    SET_HANDLER((CC_FreerContHandler)&CC_FreerContinuation::freeEvent);
  }
};

// struct CC_UpdateContinuation
//
//   Used to read the cache.conf file after the manager signals
//      a change
//
struct CC_UpdateContinuation : public Continuation {
  int
  file_update_handler(int /* etype ATS_UNUSED */, void * /* data ATS_UNUSED */)
  {
    reloadCacheControl();
    delete this;
    return EVENT_DONE;
  }
  CC_UpdateContinuation(Ptr<ProxyMutex> &m) : Continuation(m) { SET_HANDLER(&CC_UpdateContinuation::file_update_handler); }
};

int
cacheControlFile_CB(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */, RecData /* data ATS_UNUSED */,
                    void * /* cookie ATS_UNUSED */)
{
  eventProcessor.schedule_imm(new CC_UpdateContinuation(reconfig_mutex), ET_CACHE);
  return 0;
}

//
//   Begin API functions
//
bool
host_rule_in_CacheControlTable()
{
  return (CacheControlTable->hostMatch ? true : false);
}

bool
ip_rule_in_CacheControlTable()
{
  return (CacheControlTable->ipMatch ? true : false);
}

void
initCacheControl()
{
  ink_assert(CacheControlTable == nullptr);
  reconfig_mutex    = new_ProxyMutex();
  CacheControlTable = new CC_table("proxy.config.cache.control.filename", modulePrefix, &http_dest_tags);
  REC_RegisterConfigUpdateFunc("proxy.config.cache.control.filename", cacheControlFile_CB, nullptr);
}

// void reloadCacheControl()
//
//  Called when the cache.conf file changes.  Since it called
//   infrequently, we do the load of new file as blocking I/O and
//   lock aquire is also blocking
//
void
reloadCacheControl()
{
  CC_table *newTable;

  Debug("cache_control", "cache.config updated, reloading");
  eventProcessor.schedule_in(new CC_FreerContinuation(CacheControlTable), CACHE_CONTROL_TIMEOUT, ET_CACHE);
  newTable = new CC_table("proxy.config.cache.control.filename", modulePrefix, &http_dest_tags);
  ink_atomic_swap(&CacheControlTable, newTable);
}

void
getCacheControl(CacheControlResult *result, HttpRequestData *rdata, OverridableHttpConfigParams *h_txn_conf, char *tag)
{
  rdata->tag = tag;
  CacheControlTable->Match(rdata, result);

  if (h_txn_conf->cache_ignore_client_no_cache) {
    result->ignore_client_no_cache = true;
  }

  if (h_txn_conf->cache_ignore_server_no_cache) {
    result->ignore_server_no_cache = true;
  }

  if (!h_txn_conf->cache_ignore_client_cc_max_age) {
    result->ignore_client_cc_max_age = false;
  }
}

//
//   End API functions
//

// void CacheControlResult::Print()
//
//  Debugging Method
//
void
CacheControlResult::Print()
{
  printf("\t reval: %d, never-cache: %d, pin: %d, ignore-c: %d ignore-s: %d\n", revalidate_after, never_cache, pin_in_cache_for,
         ignore_client_no_cache, ignore_server_no_cache);
}

// void CacheControlRecord::Print()
//
//  Debugging Method
//
void
CacheControlRecord::Print()
{
  switch (this->directive) {
  case CC_REVALIDATE_AFTER:
    printf("\t\tDirective: %s : %d\n", CC_directive_str[CC_REVALIDATE_AFTER], this->time_arg);
    break;
  case CC_PIN_IN_CACHE:
    printf("\t\tDirective: %s : %d\n", CC_directive_str[CC_PIN_IN_CACHE], this->time_arg);
    break;
  case CC_TTL_IN_CACHE:
    printf("\t\tDirective: %s : %d\n", CC_directive_str[CC_TTL_IN_CACHE], this->time_arg);
    break;
  case CC_IGNORE_CLIENT_NO_CACHE:
  case CC_IGNORE_SERVER_NO_CACHE:
  case CC_NEVER_CACHE:
  case CC_STANDARD_CACHE:
  case CC_IGNORE_NO_CACHE:
    printf("\t\tDirective: %s\n", CC_directive_str[this->directive]);
    break;
  case CC_INVALID:
  case CC_NUM_TYPES:
    printf("\t\tDirective: INVALID\n");
    break;
  }
  if (cache_responses_to_cookies >= 0) {
    printf("\t\t  - " TWEAK_CACHE_RESPONSES_TO_COOKIES ":%d\n", cache_responses_to_cookies);
  }
  ControlBase::Print();
}

// Result CacheControlRecord::Init(matcher_line* line_info)
//
//    matcher_line* line_info - contains parsed label/value
//      pairs of the current cache.config line
//
//    Returns NULL if everything is OK
//      Otherwise, returns an error string that the caller MUST
//        DEALLOCATE with free()
//
Result
CacheControlRecord::Init(matcher_line *line_info)
{
  int time_in;
  const char *tmp;
  char *label;
  char *val;
  bool d_found = false;

  this->line_num = line_info->line_num;

  // First pass for optional tweaks.
  for (int i = 0; i < MATCHER_MAX_TOKENS && line_info->num_el; ++i) {
    bool used = false;
    label     = line_info->line[0][i];
    val       = line_info->line[1][i];
    if (!label) {
      continue;
    }

    if (strcasecmp(label, TWEAK_CACHE_RESPONSES_TO_COOKIES) == 0) {
      char *ptr = nullptr;
      int v     = strtol(val, &ptr, 0);
      if (!ptr || v < 0 || v > 4) {
        return Result::failure("Value for " TWEAK_CACHE_RESPONSES_TO_COOKIES " must be an integer in the range 0..4");
      } else {
        cache_responses_to_cookies = v;
      }
      used = true;
    }

    // Clip pair if used.
    if (used) {
      line_info->line[0][i] = nullptr;
      --(line_info->num_el);
    }
  }

  // Now look for the directive.
  for (int i = 0; i < MATCHER_MAX_TOKENS; i++) {
    label = line_info->line[0][i];
    val   = line_info->line[1][i];

    if (label == nullptr) {
      continue;
    }

    if (strcasecmp(label, "action") == 0) {
      if (strcasecmp(val, "never-cache") == 0) {
        directive = CC_NEVER_CACHE;
        d_found   = true;
      } else if (strcasecmp(val, "standard-cache") == 0) {
        directive = CC_STANDARD_CACHE;
        d_found   = true;
      } else if (strcasecmp(val, "ignore-no-cache") == 0) {
        directive = CC_IGNORE_NO_CACHE;
        d_found   = true;
      } else if (strcasecmp(val, "ignore-client-no-cache") == 0) {
        directive = CC_IGNORE_CLIENT_NO_CACHE;
        d_found   = true;
      } else if (strcasecmp(val, "ignore-server-no-cache") == 0) {
        directive = CC_IGNORE_SERVER_NO_CACHE;
        d_found   = true;
      } else {
        return Result::failure("%s Invalid action at line %d in cache.config", modulePrefix, line_num);
      }
    } else {
      if (strcasecmp(label, "revalidate") == 0) {
        directive = CC_REVALIDATE_AFTER;
        d_found   = true;
      } else if (strcasecmp(label, "pin-in-cache") == 0) {
        directive = CC_PIN_IN_CACHE;
        d_found   = true;
      } else if (strcasecmp(label, "ttl-in-cache") == 0) {
        directive = CC_TTL_IN_CACHE;
        d_found   = true;
      }
      // Process the time argument for the remaining directives
      if (d_found == true) {
        tmp = processDurationString(val, &time_in);
        if (tmp == nullptr) {
          this->time_arg = time_in;

        } else {
          return Result::failure("%s %s at line %d in cache.config", modulePrefix, tmp, line_num);
        }
      }
    }

    if (d_found == true) {
      // Consume the label/value pair we used
      line_info->line[0][i] = nullptr;
      line_info->num_el--;
      break;
    }
  }

  if (d_found == false) {
    return Result::failure("%s No directive in cache.config at line %d", modulePrefix, line_num);
  }
  // Process any modifiers to the directive, if they exist
  if (line_info->num_el > 0) {
    tmp = ProcessModifiers(line_info);

    if (tmp != nullptr) {
      return Result::failure("%s %s at line %d in cache.config", modulePrefix, tmp, line_num);
    }
  }

  return Result::ok();
}

// void CacheControlRecord::UpdateMatch(CacheControlResult* result, RequestData* rdata)
//
//    Updates the parameters in result if the this element
//     appears later in the file
//
void
CacheControlRecord::UpdateMatch(CacheControlResult *result, RequestData *rdata)
{
  bool match               = false;
  HttpRequestData *h_rdata = (HttpRequestData *)rdata;

  switch (this->directive) {
  case CC_REVALIDATE_AFTER:
    if (this->CheckForMatch(h_rdata, result->reval_line) == true) {
      result->revalidate_after = time_arg;
      result->reval_line       = this->line_num;
      match                    = true;
    }
    break;
  case CC_NEVER_CACHE:
    if (this->CheckForMatch(h_rdata, result->never_line) == true) {
      result->never_cache = true;
      result->never_line  = this->line_num;
      match               = true;
    }
    break;
  case CC_STANDARD_CACHE:
    // Standard cache just overrides never-cache
    if (this->CheckForMatch(h_rdata, result->never_line) == true) {
      result->never_cache = false;
      result->never_line  = this->line_num;
      match               = true;
    }
    break;
  case CC_IGNORE_NO_CACHE:
  // We cover both client & server cases for this directive
  //  FALLTHROUGH
  case CC_IGNORE_CLIENT_NO_CACHE:
    if (this->CheckForMatch(h_rdata, result->ignore_client_line) == true) {
      result->ignore_client_no_cache = true;
      result->ignore_client_line     = this->line_num;
      match                          = true;
    }
    if (this->directive != CC_IGNORE_NO_CACHE) {
      break;
    }
  // FALLTHROUGH
  case CC_IGNORE_SERVER_NO_CACHE:
    if (this->CheckForMatch(h_rdata, result->ignore_server_line) == true) {
      result->ignore_server_no_cache = true;
      result->ignore_server_line     = this->line_num;
      match                          = true;
    }
    break;
  case CC_PIN_IN_CACHE:
    if (this->CheckForMatch(h_rdata, result->pin_line) == true) {
      result->pin_in_cache_for = time_arg;
      result->pin_line         = this->line_num;
      match                    = true;
    }
    break;
  case CC_TTL_IN_CACHE:
    if (this->CheckForMatch(h_rdata, result->ttl_line) == true) {
      result->ttl_in_cache = time_arg;
      result->ttl_line     = this->line_num;
      // ttl-in-cache overrides never-cache
      result->never_cache = false;
      result->never_line  = this->line_num;
      match               = true;
    }
    break;
  case CC_INVALID:
  case CC_NUM_TYPES:
  default:
    // Should not get here
    Warning("Impossible directive in CacheControlRecord::UpdateMatch");
    ink_assert(0);
    break;
  }

  if (cache_responses_to_cookies >= 0) {
    result->cache_responses_to_cookies = cache_responses_to_cookies;
  }

  if (match == true) {
    char crtc_debug[80];
    if (result->cache_responses_to_cookies >= 0) {
      snprintf(crtc_debug, sizeof(crtc_debug), " [" TWEAK_CACHE_RESPONSES_TO_COOKIES "=%d]", result->cache_responses_to_cookies);
    } else {
      crtc_debug[0] = 0;
    }

    Debug("cache_control", "Matched with for %s at line %d%s", CC_directive_str[this->directive], this->line_num, crtc_debug);
  }
}
