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

/****************************************************************************

  HttpBodyFactory.cc


 ****************************************************************************/

#include "tscore/ink_platform.h"
#include "tscore/ink_sprintf.h"
#include "tscore/ink_file.h"
#include "tscore/Filenames.h"
#include "proxy/http/HttpBodyFactory.h"
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "proxy/hdrs/URL.h"
#include "proxy/logging/Log.h"
#include "proxy/logging/LogAccess.h"
#include "proxy/hdrs/HttpCompat.h"
#include "tscore/Layout.h"

//////////////////////////////////////////////////////////////////////
// The HttpBodyFactory creates HTTP response page bodies, supported //
// configurable customization and language-targeting.               //
//                                                                  //
// The body factory can be reconfigured dynamically by a manager    //
// callback, so locking is required.  The callback takes a lock,    //
// and the user entry points take a lock.  These locks may limit    //
// the speed of error page generation.                              //
//////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
//
// User-Callable APIs --- locks will be taken internally
//
////////////////////////////////////////////////////////////////////////

namespace
{

DbgCtl dbg_ctl_body_factory{"body_factory"};
DbgCtl dbg_ctl_body_factory_determine_set{"body_factory_determine_set"};
DbgCtl dbg_ctl_body_factory_instantiation{"body_factory_instantiation"};

} // end anonymous namespace

char *
HttpBodyFactory::fabricate_with_old_api(const char *type, HttpTransact::State *context, int64_t max_buffer_length,
                                        int64_t *resulting_buffer_length, char *content_language_out_buf,
                                        size_t content_language_buf_size, char *content_type_out_buf, size_t content_type_buf_size,
                                        int format_size, const char *format)
{
  char       *buffer      = nullptr;
  const char *lang_ptr    = nullptr;
  const char *charset_ptr = nullptr;
  char        url[1024];
  const char *set                      = nullptr;
  bool        found_requested_template = false;
  bool        plain_flag               = false;

  *resulting_buffer_length = 0;

  ink_strlcpy(content_language_out_buf, "en", content_language_buf_size);
  ink_strlcpy(content_type_out_buf, "text/html", content_type_buf_size);

  ///////////////////////////////////////////////////////////////////
  // if logging turned on, buffer up the URL string for simplicity //
  ///////////////////////////////////////////////////////////////////
  if (enable_logging) {
    url[0] = '\0';
    URL *u = context->hdr_info.client_request.url_get();

    if (u->valid()) { /* if url exists, copy the string into buffer */
      size_t i;
      char  *s = u->string_get(&context->arena);
      for (i = 0; (i < sizeof(url) - 1) && s[i]; i++) {
        url[i] = s[i];
      }
      url[i] = '\0';
      if (s) {
        context->arena.str_free(s);
      }
    }
  }

  ///////////////////////////////////////////////
  // if suppressing this response, return NULL //
  ///////////////////////////////////////////////
  if (is_response_suppressed(context)) {
    if (enable_logging) {
      Log::error("BODY_FACTORY: suppressing '%s' response for url '%s'", type, url);
    }
    return nullptr;
  }

  lock(); // body factory lock

  //////////////////////////////////////////////////////////////////////////////////
  // if language-targeting activated, get client Accept-Language & Accept-Charset //
  //////////////////////////////////////////////////////////////////////////////////

  StrList acpt_language_list(false);
  StrList acpt_charset_list(false);

  if (enable_customizations == 2) {
    context->hdr_info.client_request.value_get_comma_list(static_cast<std::string_view>(MIME_FIELD_ACCEPT_LANGUAGE),
                                                          &acpt_language_list);
    context->hdr_info.client_request.value_get_comma_list(static_cast<std::string_view>(MIME_FIELD_ACCEPT_CHARSET),
                                                          &acpt_charset_list);
  }
  ///////////////////////////////////////////
  // check if we don't need to format body //
  ///////////////////////////////////////////

  buffer = (format == nullptr) ? nullptr : ats_strndup(format, format_size);
  if (buffer != nullptr && format_size > 0) {
    *resulting_buffer_length = format_size > max_buffer_length ? 0 : format_size;
    plain_flag               = true;
  }
  /////////////////////////////////////////////////////////
  // try to fabricate the desired type of error response //
  /////////////////////////////////////////////////////////
  if (buffer == nullptr) {
    buffer =
      fabricate(&acpt_language_list, &acpt_charset_list, type, context, resulting_buffer_length, &lang_ptr, &charset_ptr, &set);
    found_requested_template = (buffer != nullptr);
  }
  /////////////////////////////////////////////////////////////
  // if failed, try to fabricate the default custom response //
  /////////////////////////////////////////////////////////////
  if (buffer == nullptr) {
    if (is_response_body_precluded(context->http_return_code)) {
      *resulting_buffer_length = 0;
      unlock();
      return nullptr;
    }
    buffer = fabricate(&acpt_language_list, &acpt_charset_list, "default", context, resulting_buffer_length, &lang_ptr,
                       &charset_ptr, &set);
  }

  ///////////////////////////////////
  // enforce the max buffer length //
  ///////////////////////////////////
  if (buffer && (*resulting_buffer_length > max_buffer_length)) {
    if (enable_logging) {
      Log::error(("BODY_FACTORY: template '%s/%s' consumed %" PRId64 " bytes, "
                  "exceeding %" PRId64 " byte limit, using internal default"),
                 set, type, *resulting_buffer_length, max_buffer_length);
    }
    *resulting_buffer_length = 0;
    buffer                   = static_cast<char *>(ats_free_null(buffer));
  }
  /////////////////////////////////////////////////////////////////////
  // handle return of instantiated template and generate the content //
  // language and content type return values                         //
  /////////////////////////////////////////////////////////////////////
  if (buffer) { // got an instantiated template
    if (!plain_flag) {
      snprintf(content_language_out_buf, content_language_buf_size, "%s", lang_ptr);
      snprintf(content_type_out_buf, content_type_buf_size, "text/html; charset=%s", charset_ptr);
    }

    if (enable_logging) {
      if (found_requested_template) { // got exact template
        Log::error(("BODY_FACTORY: using custom template "
                    "'%s/%s' for url '%s' (language '%s', charset '%s')"),
                   set, type, url, lang_ptr, charset_ptr);
      } else { // got default template
        Log::error(("BODY_FACTORY: can't find custom template "
                    "'%s/%s', using '%s/%s' for url '%s' (language '%s', charset '%s')"),
                   set, type, set, "default", url, lang_ptr, charset_ptr);
      }
    }
  } else { // no template
    if (enable_logging) {
      Log::error(("BODY_FACTORY: can't find templates '%s' or '%s' for url `%s'"), type, "default", url);
    }
  }
  unlock();

  return buffer;
}

void
HttpBodyFactory::dump_template_tables(FILE *fp)
{
  lock();
  if (table_of_sets) {
    for (const auto &it1 : *table_of_sets.get()) {
      HttpBodySet *body_set = static_cast<HttpBodySet *>(it1.second);
      if (body_set) {
        fprintf(fp, "set %s: name '%s', lang '%s', charset '%s'\n", it1.first.c_str(), body_set->set_name,
                body_set->content_language, body_set->content_charset);

        ///////////////////////////////////////////
        // loop over body-types->body hash table //
        ///////////////////////////////////////////

        ink_assert(body_set->is_sane());
        if (body_set->table_of_pages) {
          for (const auto &it2 : *body_set->table_of_pages.get()) {
            fprintf(fp, "  %-30s: %" PRId64 " bytes\n", it2.first.c_str(), it2.second->byte_count);
          }
        }
      }
    }
  }

  unlock();
}

////////////////////////////////////////////////////////////////////////
//
// Configuration Change Callback
//
////////////////////////////////////////////////////////////////////////

static int
config_callback(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */, RecData /* data ATS_UNUSED */,
                void *cookie)
{
  HttpBodyFactory *body_factory = static_cast<HttpBodyFactory *>(cookie);
  body_factory->reconfigure();
  return 0;
}

void
HttpBodyFactory::reconfigure()
{
  bool all_found;

  lock();
  sanity_check();

  if (!callbacks_established) {
    unlock();
    return;
  } // callbacks not setup right

  ////////////////////////////////////////////
  // extract relevant records.yaml values //
  ////////////////////////////////////////////

  Dbg(dbg_ctl_body_factory, "config variables changed, reconfiguring...");

  all_found = true;

  // enable_customizations if records.yaml set
  auto e{RecGetRecordInt("proxy.config.body_factory.enable_customizations")};
  enable_customizations = (e.has_value() ? e.value() : 0);
  all_found             = all_found && e.has_value();
  Dbg(dbg_ctl_body_factory, "enable_customizations = %d (found = %d)", enable_customizations, e.has_value());

  e              = RecGetRecordInt("proxy.config.body_factory.enable_logging");
  enable_logging = (e.has_value() ? (e.value() ? true : false) : false);
  all_found      = all_found && e.has_value();
  Dbg(dbg_ctl_body_factory, "enable_logging = %d (found = %d)", enable_logging, e.has_value());

  ats_scoped_str directory_of_template_sets;

  {
    auto rec_str{RecGetRecordStringAlloc("proxy.config.body_factory.template_sets_dir")};
    all_found = all_found && rec_str;
    if (rec_str) {
      directory_of_template_sets = Layout::get()->relative(rec_str ? rec_str.value() : std::string_view{nullptr, 0});
      if (access(directory_of_template_sets, R_OK) < 0) {
        Warning("Unable to access() directory '%s': %d, %s", (const char *)directory_of_template_sets, errno, strerror(errno));
        if (TSSystemState::is_initializing()) {
          Emergency(" Please set 'proxy.config.body_factory.template_sets_dir' ");
        } else {
          Warning(" Please set 'proxy.config.body_factory.template_sets_dir' ");
        }
      }
    }
  }

  Dbg(dbg_ctl_body_factory, "directory_of_template_sets = '%s' ", (const char *)directory_of_template_sets);

  if (!all_found) {
    Warning("config changed, but can't fetch all proxy.config.body_factory values");
  }

  /////////////////////////////////////////////
  // clear out previous template hash tables //
  /////////////////////////////////////////////

  nuke_template_tables();

  /////////////////////////////////////////////////////////////
  // at this point, the body hash table is gone, so we start //
  // building a new one, by scanning the template directory. //
  /////////////////////////////////////////////////////////////

  if (directory_of_template_sets) {
    table_of_sets = load_sets_from_directory(directory_of_template_sets);
  }

  unlock();
}

////////////////////////////////////////////////////////////////////////
//
// class HttpBodyFactory
//
////////////////////////////////////////////////////////////////////////

HttpBodyFactory::HttpBodyFactory()
{
  int  i;
  bool status, no_registrations_failed;

  ////////////////////////////////////
  // initialize first-time defaults //
  ////////////////////////////////////
  ink_mutex_init(&mutex);

  //////////////////////////////////////////////////////
  // set up management configuration-change callbacks //
  //////////////////////////////////////////////////////

  static const char *config_record_names[] = {"proxy.config.body_factory.enable_customizations",
                                              "proxy.config.body_factory.enable_logging",
                                              "proxy.config.body_factory.template_sets_dir", nullptr};

  no_registrations_failed = true;
  for (i = 0; config_record_names[i] != nullptr; i++) {
    status = RecRegisterConfigUpdateCb(config_record_names[i], config_callback, (void *)this);
    if (status != REC_ERR_OKAY) {
      Warning("couldn't register variable '%s', is %s up to date?", config_record_names[i], ts::filename::RECORDS);
    }
    no_registrations_failed = no_registrations_failed && (status == REC_ERR_OKAY);
  }

  if (no_registrations_failed == false) {
    Warning("couldn't setup all body_factory callbacks, disabling body_factory");
  } else {
    Dbg(dbg_ctl_body_factory, "all callbacks established successfully");
    callbacks_established = true;
    reconfigure();
  }
}

HttpBodyFactory::~HttpBodyFactory()
{
  // FIX: need to implement destructor
  table_of_sets.reset(nullptr);
}

// LOCKING: must be called with lock taken
char *
HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_list, const char *type, HttpTransact::State *context,
                           int64_t *buffer_length_return, const char **content_language_return, const char **content_charset_return,
                           const char **set_return)
{
  char       *buffer;
  const char *pType = context->txn_conf->body_factory_template_base;
  const char *set;
  char        template_base[PATH_NAME_MAX];

  if (set_return) {
    *set_return = "???";
  }
  *content_language_return = nullptr;
  *content_charset_return  = nullptr;

  Dbg(dbg_ctl_body_factory, "calling fabricate(type '%s')", type);
  *buffer_length_return = 0;

  // if error body suppressed, return NULL
  if (is_response_suppressed(context)) {
    Dbg(dbg_ctl_body_factory, "  error suppression enabled, returning NULL template");
    return nullptr;
  }
  // if custom error pages are disabled, return NULL
  if (!enable_customizations) {
    Dbg(dbg_ctl_body_factory, "  customization disabled, returning NULL template");
    return nullptr;
  }

  // what set should we use (language target if enable_customizations == 2)
  if (enable_customizations == 2) {
    set = determine_set_by_language(acpt_language_list, acpt_charset_list);
  } else if (enable_customizations == 3) {
    set = determine_set_by_host(context);
  } else if (is_response_body_precluded(context->http_return_code)) {
    return nullptr;
  } else {
    set = "default";
  }
  if (set_return) {
    *set_return = set;
  }

  HttpBodyTemplate *t        = nullptr;
  HttpBodySet      *body_set = nullptr;
  if (pType != nullptr && 0 != *pType && 0 != strncmp(pType, "NONE", 4)) {
    snprintf(template_base, sizeof(template_base), "%s_%s", pType, type);
    t = find_template(set, template_base, &body_set);
    // Check for default alternate.
    if (t == nullptr) {
      snprintf(template_base, sizeof(template_base), "%s_default", pType);
      t = find_template(set, template_base, &body_set);
    }
  }

  // Check for base customizations if specializations didn't work.
  if (t == nullptr) {
    if (is_response_body_precluded(context->http_return_code)) {
      return nullptr;
    }
    t = find_template(set, type, &body_set); // this executes if the template_base is wrong and doesn't exist
  }

  if (t == nullptr) {
    Dbg(dbg_ctl_body_factory, "  can't find template, returning NULL template");
    return nullptr;
  }

  *content_language_return = body_set->content_language;
  *content_charset_return  = body_set->content_charset;

  // build the custom error page
  buffer = t->build_instantiated_buffer(context, buffer_length_return);
  return buffer;
}

// LOCKING: must be called with lock taken
const char *
HttpBodyFactory::determine_set_by_host(HttpTransact::State *context)
{
  const char *set;
  int         host_len = context->hh_info.host_len;
  char        host_buffer[host_len + 1];
  strncpy(host_buffer, context->hh_info.request_host, host_len);
  host_buffer[host_len] = '\0';
  if (auto it = table_of_sets->find(host_buffer); it != table_of_sets->end()) {
    set = it->first.c_str();
  } else {
    set = "default";
  }
  return set;
}

const char *
HttpBodyFactory::determine_set_by_language(std::unique_ptr<BodySetTable> &table_of_sets, StrList *acpt_language_list,
                                           StrList *acpt_charset_list, float *Q_best_ptr, int *La_best_ptr, int *Lc_best_ptr,
                                           int *I_best_ptr)
{
  float       Q, Ql, Qc, Q_best;
  int         I, Idummy, I_best;
  int         La, Lc, La_best, Lc_best;
  int         is_the_default_set;
  const char *set_best;

  set_best = "default";
  Q_best   = 0.00001;
  La_best  = 0;
  Lc_best  = INT_MAX;
  I_best   = INT_MAX;

  Dbg(dbg_ctl_body_factory_determine_set, "  INITIAL: [ set_best='%s', Q=%g, La=%d, Lc=%d, I=%d ]", set_best, Q_best, La_best,
      Lc_best, I_best);

  // FIX: eliminate this special case (which doesn't work anyway), by properly
  //      handling empty lists and empty pieces in match_accept_XXX

  // if no Accept-Language or Accept-Charset, just return default
  if ((acpt_language_list->count == 0) && (acpt_charset_list->count == 0)) {
    Q_best = 1;
    Dbg(dbg_ctl_body_factory_determine_set, "  no constraints => returning '%s'", set_best);
    goto done;
  }

  if (table_of_sets) {
    ///////////////////////////////////////////
    // loop over set->body-types hash table //
    ///////////////////////////////////////////
    for (const auto &it : *table_of_sets.get()) {
      const char         *set_name = it.first.c_str();
      HttpBodySetRawData *body_set = it.second;

      if ((it.first.empty()) || (body_set->table_of_pages == nullptr)) {
        continue;
      }

      //////////////////////////////////////////////////////////////////////
      // Take this error page language and match it against the           //
      // Accept-Language string passed in, to evaluate the match          //
      // quality.  Disable wildcard processing so we use "default"        //
      // if no set explicitly matches.  We also get back the index        //
      // of the match and the length of the match.                        //
      //                                                                  //
      // We optimize the match in a couple of ways:                       //
      //   (a) if Q is better ==> wins, else if tie,                      //
      //   (b) if accept tag length La is bigger ==> wins, else if tie,   //
      //   (c) if content tag length Lc is smaller ==> wins, else if tie, //
      //   (d) if index position I is smaller ==> wins                    //
      //////////////////////////////////////////////////////////////////////

      is_the_default_set = (strcmp(set_name, "default") == 0);

      Dbg(dbg_ctl_body_factory_determine_set, "  --- SET: %-8s (Content-Language '%s', Content-Charset '%s')", set_name,
          body_set->content_language, body_set->content_charset);

      // if no Accept-Language hdr at all, treat as a wildcard that
      // slightly prefers "default".
      if (acpt_language_list->count == 0) {
        Ql = (is_the_default_set ? 1.0001 : 1.000);
        La = 0;
        Lc = INT_MAX;
        I  = 1;
        Dbg(dbg_ctl_body_factory_determine_set, "      SET: [%-8s] A-L not present => [ Ql=%g, La=%d, Lc=%d, I=%d ]", set_name, Ql,
            La, Lc, I);
      } else {
        Lc = strlen(body_set->content_language);
        Ql = HttpCompat::match_accept_language(body_set->content_language, Lc, acpt_language_list, &La, &I, true);
        Dbg(dbg_ctl_body_factory_determine_set, "      SET: [%-8s] A-L match value => [ Ql=%g, La=%d, Lc=%d, I=%d ]", set_name, Ql,
            La, Lc, I);
      }

      /////////////////////////////////////////////////////////////
      // Take this error page language and match it against the  //
      // Accept-Charset string passed in, to evaluate the match  //
      // quality.  Disable wildcard processing so that only      //
      // explicit values match.  (Many browsers will send along  //
      // "*" with all lists, and we really don't want to send    //
      // strange character sets for these people --- we'd rather //
      // use a more portable "default" set.  The index value we  //
      // get back isn't used, because it's a little hard to know //
      // how to tradeoff language indices vs. charset indices.   //
      // If someone cares, we could surely work charset indices  //
      // into the sorting computation below.                     //
      /////////////////////////////////////////////////////////////

      // if no Accept-Charset hdr at all, treat as a wildcard that
      // slightly prefers "default".
      if (acpt_charset_list->count == 0) {
        Qc     = (is_the_default_set ? 1.0001 : 1.000);
        Idummy = 1;
        Dbg(dbg_ctl_body_factory_determine_set, "      SET: [%-8s] A-C not present => [ Qc=%g ]", set_name, Qc);
      } else {
        Qc = HttpCompat::match_accept_charset(body_set->content_charset, strlen(body_set->content_charset), acpt_charset_list,
                                              &Idummy, true);
        Dbg(dbg_ctl_body_factory_determine_set, "      SET: [%-8s] A-C match value => [ Qc=%g ]", set_name, Qc);
      }

      /////////////////////////////////////////////////////////////////
      // We get back the Q value, the matching field length, and the //
      // matching field index.  We sort by largest Q value, but if   //
      // there is a Q tie, we sub sort on longer matching length,    //
      // and if there is a tie on Q and L, we sub sort on position   //
      // index, preferring values earlier in Accept-Language list.   //
      /////////////////////////////////////////////////////////////////

      Q = std::min(Ql, Qc);

      //////////////////////////////////////////////////////////
      // normally the Q for default pages should be slightly  //
      // less than for normal pages, but default pages should //
      // always match to a slight level, in case everything   //
      // else doesn't match (matches with Q=0).               //
      //////////////////////////////////////////////////////////

      if (is_the_default_set) {
        Q = Q + -0.00005;
        if (Q < 0.00001) {
          Q = 0.00001;
        }
      }

      Dbg(dbg_ctl_body_factory_determine_set, "      NEW: [ set='%s', Q=%g, La=%d, Lc=%d, I=%d ]", set_name, Q, La, Lc, I);
      Dbg(dbg_ctl_body_factory_determine_set, "      OLD: [ set='%s', Q=%g, La=%d, Lc=%d, I=%d ]", set_best, Q_best, La_best,
          Lc_best, I_best);

      if (((Q > Q_best)) || ((Q == Q_best) && (La > La_best)) || ((Q == Q_best) && (La == La_best) && (Lc < Lc_best)) ||
          ((Q == Q_best) && (La == La_best) && (Lc == Lc_best) && (I < I_best))) {
        Q_best   = Q;
        La_best  = La;
        Lc_best  = Lc;
        I_best   = I;
        set_best = set_name;

        Dbg(dbg_ctl_body_factory_determine_set, "   WINNER: [ set_best='%s', Q=%g, La=%d, Lc=%d, I=%d ]", set_best, Q_best, La_best,
            Lc_best, I_best);
      } else {
        Dbg(dbg_ctl_body_factory_determine_set, "    LOSER: [ set_best='%s', Q=%g, La=%d, Lc=%d, I=%d ]", set_best, Q_best, La_best,
            Lc_best, I_best);
      }
    }
  }

done:

  *Q_best_ptr  = Q_best;
  *La_best_ptr = La_best;
  *Lc_best_ptr = Lc_best;
  *I_best_ptr  = I_best;
  return set_best;
}

// LOCKING: must be called with lock taken
const char *
HttpBodyFactory::determine_set_by_language(StrList *acpt_language_list, StrList *acpt_charset_list)
{
  float       Q_best;
  const char *set_best;
  int         La_best, Lc_best, I_best;

  set_best = determine_set_by_language(table_of_sets, acpt_language_list, acpt_charset_list, &Q_best, &La_best, &Lc_best, &I_best);

  return set_best;
}

// LOCKING: must be called with lock taken
HttpBodyTemplate *
HttpBodyFactory::find_template(const char *set, const char *type, HttpBodySet **body_set_return)
{
  Dbg(dbg_ctl_body_factory, "calling find_template(%s,%s)", set, type);

  *body_set_return = nullptr;

  if (table_of_sets == nullptr || !set || !type) {
    return nullptr;
  }
  if (auto it = table_of_sets->find(set); it != table_of_sets->end()) {
    HttpBodySet *body_set = static_cast<HttpBodySet *>(it->second);
    if (body_set->table_of_pages == nullptr) {
      return nullptr;
    }

    if (auto it_page = body_set->table_of_pages->find(type); it_page != body_set->table_of_pages->end()) {
      auto &t = it_page->second;
      if ((t == nullptr) || (!t->is_sane())) {
        return nullptr;
      }
      *body_set_return = body_set;

      Dbg(dbg_ctl_body_factory, "find_template(%s,%s) -> (file %s, length %" PRId64 ", lang '%s', charset '%s')", set, type,
          t->template_pathname, t->byte_count, body_set->content_language, body_set->content_charset);

      return t.get();
    }
  }
  Dbg(dbg_ctl_body_factory, "find_template(%s,%s) -> NULL", set, type);

  return nullptr;
}

// LOCKING: must be called with lock taken
bool
HttpBodyFactory::is_response_suppressed(HttpTransact::State *context)
{
  // Since a tunnel may not always be an SSL connection,
  // we may want to return an error message.
  // Even if it's an SSL connection, it won't cause any harm
  // as the connection is going to be closed anyway.
  /*
     if (context->client_info.port_attribute == SERVER_PORT_BLIND_TUNNEL) {
     // Blind SSL tunnels always suppress error messages
     return true;
     } else
   */
  if (context->txn_conf->response_suppression_mode == 0) {
    return false;
  } else if (context->txn_conf->response_suppression_mode == 1) {
    return true;
  } else if (context->txn_conf->response_suppression_mode == 2) {
    return context->request_data.internal_txn;
  } else {
    return false;
  }
}

// LOCKING: must be called with lock taken
void
HttpBodyFactory::nuke_template_tables()
{
  if (table_of_sets) {
    Dbg(dbg_ctl_body_factory, "deleting pre-existing template tables");
  } else {
    Dbg(dbg_ctl_body_factory, "no pre-existing template tables");
  }
  if (table_of_sets) {
    ///////////////////////////////////////////
    // loop over set->body-types hash table //
    ///////////////////////////////////////////
    for (const auto &it : *table_of_sets.get()) {
      HttpBodySet *body_set = static_cast<HttpBodySet *>(it.second);
      ink_assert(body_set->is_sane());
      if (body_set->table_of_pages) {
        ///////////////////////////////////////////
        // loop over body-types->body hash table //
        ///////////////////////////////////////////
        for (auto &it_page : *body_set->table_of_pages.get()) {
          it_page.second.reset(nullptr);
        }
        body_set->table_of_pages.reset(nullptr);
      }
      delete body_set;
    }
    table_of_sets.reset(nullptr);
  }
}

// LOCKING: must be called with lock taken
std::unique_ptr<HttpBodyFactory::BodySetTable>
HttpBodyFactory::load_sets_from_directory(char *set_dir)
{
  DIR                                           *dir;
  struct dirent                                 *dirEntry;
  std::unique_ptr<HttpBodyFactory::BodySetTable> new_table_of_sets;

  if (set_dir == nullptr) {
    return nullptr;
  }

  Dbg(dbg_ctl_body_factory, "load_sets_from_directory(%s)", set_dir);

  //////////////////////////////////////////////////
  // try to open the requested template directory //
  //////////////////////////////////////////////////

  dir = opendir(set_dir);
  if (dir == nullptr) {
    Warning("can't open response template directory '%s' (%s)", set_dir, (strerror(errno) ? strerror(errno) : "unknown reason"));
    Warning("no response templates --- using default error pages");
    return nullptr;
  }

  new_table_of_sets.reset(new HttpBodyFactory::BodySetTable);

  //////////////////////////////////////////
  // loop over each language subdirectory //
  //////////////////////////////////////////

  while ((dirEntry = readdir(dir))) {
    int         status;
    struct stat stat_buf;
    char        subdir[MAXPATHLEN + 1];

    //////////////////////////////////////////////////////
    // ensure a subdirectory, and not starting with '.' //
    //////////////////////////////////////////////////////

    if ((dirEntry->d_name)[0] == '.') {
      continue;
    }

    ink_filepath_make(subdir, sizeof(subdir), set_dir, dirEntry->d_name);
    status = stat(subdir, &stat_buf);
    if (status != 0) {
      continue; // can't stat
    }

    if (!S_ISDIR(stat_buf.st_mode)) {
      continue; // not a dir
    }

    ///////////////////////////////////////////////////////////
    // at this point, 'subdir' might be a valid template dir //
    ///////////////////////////////////////////////////////////

    HttpBodySet *body_set = load_body_set_from_directory(dirEntry->d_name, subdir);
    if (body_set != nullptr) {
      Dbg(dbg_ctl_body_factory, "  %s -> %p", dirEntry->d_name, body_set);
      new_table_of_sets->emplace(dirEntry->d_name, body_set);
    }
  }

  closedir(dir);

  return new_table_of_sets;
}

// LOCKING: must be called with lock taken
HttpBodySet *
HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir)
{
  DIR              *dir;
  int               status;
  struct stat       stat_buf;
  struct dirent    *dirEntry;
  char              path[MAXPATHLEN + 1];
  static const char BASED_DEFAULT[] = "_default";

  ////////////////////////////////////////////////
  // ensure we can open tmpl_dir as a directory //
  ////////////////////////////////////////////////

  Dbg(dbg_ctl_body_factory, "  load_body_set_from_directory(%s)", tmpl_dir);
  dir = opendir(tmpl_dir);
  if (dir == nullptr) {
    return nullptr;
  }

  /////////////////////////////////////////////
  // ensure a .body_factory_info file exists //
  /////////////////////////////////////////////

  ink_filepath_make(path, sizeof(path), tmpl_dir, ".body_factory_info");
  status = stat(path, &stat_buf);
  if ((status < 0) || !S_ISREG(stat_buf.st_mode)) {
    Warning("Missing .body_factory_info in %s.  Not loading body_factory templates", tmpl_dir);
    closedir(dir);
    return nullptr;
  }
  Dbg(dbg_ctl_body_factory, "    found '%s'", path);

  /////////////////////////////////////////////////////////////////
  // create body set, and loop over template files, loading them //
  /////////////////////////////////////////////////////////////////

  HttpBodySet *body_set = new HttpBodySet;
  body_set->init(set_name, tmpl_dir);

  Dbg(dbg_ctl_body_factory, "  body_set = %p (set_name '%s', lang '%s', charset '%s')", body_set, body_set->set_name,
      body_set->content_language, body_set->content_charset);

  while ((dirEntry = readdir(dir))) {
    size_t d_len = strlen(dirEntry->d_name);

    ///////////////////////////////////////////////////////////////
    // all template files must have a file name of the form      //
    // - <type>#<subtype>                                        //
    // - <base>_<type>#<subtype>                                 //
    // - <base>_default   [based default]                        //
    // - default          [global default]                       //
    ///////////////////////////////////////////////////////////////

    if (!(nullptr != strchr(dirEntry->d_name, '#') || (0 == strcmp(dirEntry->d_name, "default")) ||
          (d_len >= sizeof(BASED_DEFAULT) && 0 == strcmp(dirEntry->d_name + d_len - (sizeof(BASED_DEFAULT) - 1), BASED_DEFAULT)))) {
      continue;
    }

    snprintf(path, sizeof(path), "%s/%s", tmpl_dir, dirEntry->d_name);
    status = stat(path, &stat_buf);
    if (status != 0) {
      continue; // can't stat
    }

    if (!S_ISREG(stat_buf.st_mode)) {
      continue; // not a file
    }

    ////////////////////////////////
    // read in this template file //
    ////////////////////////////////

    auto tmpl = std::make_unique<HttpBodyTemplate>();
    if (tmpl->load_from_file(tmpl_dir, dirEntry->d_name)) {
      Dbg(dbg_ctl_body_factory, "      %s -> %p", dirEntry->d_name, tmpl.get());
      body_set->set_template_by_name(dirEntry->d_name, std::move(tmpl));
    }
  }

  closedir(dir);
  return body_set;
}

////////////////////////////////////////////////////////////////////////
//
// class HttpBodySet
//
////////////////////////////////////////////////////////////////////////

HttpBodySet::HttpBodySet()
{
  magic = HTTP_BODY_SET_MAGIC;

  set_name         = nullptr;
  content_language = nullptr;
  content_charset  = nullptr;

  table_of_pages = nullptr;
}

HttpBodySet::~HttpBodySet()
{
  ats_free(set_name);
  ats_free(content_language);
  ats_free(content_charset);
  table_of_pages.reset(nullptr);
}

int
HttpBodySet::init(char *set, char *dir)
{
  int  fd, lineno, lines_added = 0;
  char info_path[MAXPATHLEN];

  char buffer[1024], name[1025], value[1024];

  ink_filepath_make(info_path, sizeof(info_path), dir, ".body_factory_info");
  fd = open(info_path, O_RDONLY);
  if (fd < 0) {
    return -1;
  }

  this->set_name = ats_strdup(set);
  this->table_of_pages.reset(new TemplateTable);

  lineno = 0;

  while (true) {
    char *name_s, *name_e, *value_s, *value_e, *hash;

    ++lineno;
    int bytes = ink_file_fd_readline(fd, sizeof(buffer), buffer);
    if (bytes <= 0) {
      break;
    }

    ///////////////////////////////////////////////
    // chop anything on and after first '#' sign //
    ///////////////////////////////////////////////

    hash = index(buffer, '#');
    if (hash) {
      *hash = '\0';

      ////////////////////////////////
      // find start and end of name //
      ////////////////////////////////
    }
    name_s = buffer;
    while (*name_s && ParseRules::is_wslfcr(*name_s)) {
      ++name_s;
    }

    name_e = name_s;
    while (*name_e && ParseRules::is_http_field_name(*name_e)) {
      ++name_e;
    }

    if (name_s == name_e) {
      continue; // blank line
    }

    /////////////////////////////////
    // find start and end of value //
    /////////////////////////////////

    value_s = name_e;
    while (*value_s && (ParseRules::is_wslfcr(*value_s))) {
      ++value_s;
    }
    if (*value_s != ':') {
      Warning("ignoring invalid body factory info line #%d in %s", lineno, info_path);
      continue;
    }
    ++value_s; // skip the colon
    while (*value_s && (ParseRules::is_wslfcr(*value_s))) {
      ++value_s;
    }
    value_e = buffer + strlen(buffer) - 1;
    while ((value_e > value_s) && ParseRules::is_wslfcr(*(value_e - 1))) {
      --value_e;
    }

    /////////////////////////////////
    // insert line into hash table //
    /////////////////////////////////

    memcpy(name, name_s, name_e - name_s);
    name[name_e - name_s] = '\0';

    memcpy(value, value_s, value_e - value_s);
    value[value_e - value_s] = '\0';

    //////////////////////////////////////////////////
    // so far, we only support 2 pieces of metadata //
    //////////////////////////////////////////////////

    if (strcasecmp(name, "Content-Language") == 0) {
      ats_free(this->content_language);
      this->content_language = ats_strdup(value);
    } else if (strcasecmp(name, "Content-Charset") == 0) {
      ats_free(this->content_charset);
      this->content_charset = ats_strdup(value);
    }
  }

  ////////////////////////////////////////////////////
  // fill in default language & charset, if not set //
  ////////////////////////////////////////////////////

  if (!this->content_language) {
    if (strcmp(set, "default") == 0) {
      this->content_language = ats_strdup("en");
    } else {
      this->content_language = ats_strdup(set);
    }
  }
  if (!this->content_charset) {
    this->content_charset = ats_strdup("utf-8");
  }

  close(fd);
  return lines_added;
}

HttpBodyTemplate *
HttpBodySet::get_template_by_name(const char *name)
{
  Dbg(dbg_ctl_body_factory, "    calling get_template_by_name(%s)", name);

  if (table_of_pages == nullptr) {
    return nullptr;
  }

  if (auto it = table_of_pages->find(name); it != table_of_pages->end()) {
    auto &t = it->second;
    if ((t == nullptr) || (!t->is_sane())) {
      return nullptr;
    }
    Dbg(dbg_ctl_body_factory, "    get_template_by_name(%s) -> (file %s, length %" PRId64 ")", name, t->template_pathname,
        t->byte_count);
    return t.get();
  }
  Dbg(dbg_ctl_body_factory, "    get_template_by_name(%s) -> NULL", name);
  return nullptr;
}

void
HttpBodySet::set_template_by_name(const char *name, std::unique_ptr<HttpBodyTemplate> t)
{
  if (name) {
    table_of_pages->emplace(name, std::move(t));
  }
}

////////////////////////////////////////////////////////////////////////
//
// class HttpBodyTemplate
//
////////////////////////////////////////////////////////////////////////

HttpBodyTemplate::HttpBodyTemplate()
{
  magic             = HTTP_BODY_TEMPLATE_MAGIC;
  byte_count        = 0;
  template_buffer   = nullptr;
  template_pathname = nullptr;
}

HttpBodyTemplate::~HttpBodyTemplate()
{
  reset();
}

void
HttpBodyTemplate::reset()
{
  ats_free(template_buffer);
  template_buffer = nullptr;
  byte_count      = 0;
  ats_free(template_pathname);
}

int
HttpBodyTemplate::load_from_file(char *dir, char *file)
{
  int         fd, status;
  int64_t     bytes_read;
  struct stat stat_buf;
  char        path[MAXPATHLEN + 1];
  char       *new_template_buffer;
  int64_t     new_byte_count;

  ////////////////////////////////////
  // ensure this is actually a file //
  ////////////////////////////////////

  snprintf(path, sizeof(path), "%s/%s", dir, file);
  // coverity[fs_check_call]
  status = stat(path, &stat_buf);
  if (status != 0) {
    return 0;
  }
  if (!S_ISREG(stat_buf.st_mode)) {
    return 0;
  }

  ///////////////////
  // open the file //
  ///////////////////

  // coverity[toctou]
  fd = open(path, O_RDONLY);
  if (fd < 0) {
    return 0;
  }

  ////////////////////////////////////////
  // read in the template file contents //
  ////////////////////////////////////////

  new_byte_count                      = stat_buf.st_size;
  new_template_buffer                 = static_cast<char *>(ats_malloc(new_byte_count + 1));
  bytes_read                          = read(fd, new_template_buffer, new_byte_count);
  new_template_buffer[new_byte_count] = '\0';
  close(fd);

  ///////////////////////////
  // check for read errors //
  ///////////////////////////

  if (bytes_read != new_byte_count) {
    Warning("reading template file '%s', got %" PRId64 " bytes instead of %" PRId64 " (%s)", path, bytes_read, new_byte_count,
            (strerror(errno) ? strerror(errno) : "unknown error"));
    ats_free(new_template_buffer);
    return 0;
  }

  Dbg(dbg_ctl_body_factory, "    read %" PRId64 " bytes from '%s'", new_byte_count, path);

  /////////////////////////////////
  // actually commit the changes //
  /////////////////////////////////

  reset();
  template_buffer   = new_template_buffer;
  byte_count        = new_byte_count;
  template_pathname = ats_strdup(path);

  return 1;
}

char *
HttpBodyTemplate::build_instantiated_buffer(HttpTransact::State *context, int64_t *buflen_return)
{
  char *buffer = nullptr;

  Dbg(dbg_ctl_body_factory_instantiation, "    before instantiation: [%s]", template_buffer);

  LogAccess la(context->state_machine);

  buffer = resolve_logfield_string(&la, template_buffer);

  *buflen_return = ((buffer == nullptr) ? 0 : strlen(buffer));
  Dbg(dbg_ctl_body_factory_instantiation, "    after instantiation: [%s]", buffer);
  Dbg(dbg_ctl_body_factory, "  returning %" PRId64 " byte instantiated buffer", *buflen_return);

  return buffer;
}
