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

#include "tscore/ink_platform.h"
#include "tscore/ink_memory.h"
#include "tscore/ink_file.h"
#include "tscore/I_Layout.h"
#include "tscore/Filenames.h"
#include "DiagsConfig.h"
#include "records/P_RecCore.h"

//////////////////////////////////////////////////////////////////////////////
//
//      void reconfigure_diags()
//
//      This function extracts the current diags configuration settings from
//      records.config, and rebuilds the Diags data structures.
//
//////////////////////////////////////////////////////////////////////////////

void
DiagsConfig::reconfigure_diags()
{
  int i, e;
  char *p, *dt, *at;
  DiagsConfigState c;
  bool found, all_found;

  static struct {
    const char *config_name;
    DiagsLevel level;
  } output_records[] = {
    {"proxy.config.diags.output.diag", DL_Diag},           {"proxy.config.diags.output.debug", DL_Debug},
    {"proxy.config.diags.output.status", DL_Status},       {"proxy.config.diags.output.note", DL_Note},
    {"proxy.config.diags.output.warning", DL_Warning},     {"proxy.config.diags.output.error", DL_Error},
    {"proxy.config.diags.output.fatal", DL_Fatal},         {"proxy.config.diags.output.alert", DL_Alert},
    {"proxy.config.diags.output.emergency", DL_Emergency}, {nullptr, DL_Undefined},
  };

  if (!callbacks_established) {
    register_diags_callbacks();
  }
  ////////////////////////////////////////////
  // extract relevant records.config values //
  ////////////////////////////////////////////

  all_found = true;

  // initial value set to 0 or 1 based on command line tags
  c.enabled[DiagsTagType_Debug]  = (_diags->base_debug_tags != nullptr);
  c.enabled[DiagsTagType_Action] = (_diags->base_action_tags != nullptr);

  // enabled if records.config set

  e = static_cast<int>(REC_readInteger("proxy.config.diags.debug.enabled", &found));
  if (e && found) {
    c.enabled[DiagsTagType_Debug] = e; // implement OR logic
  }
  all_found = all_found && found;

  e = static_cast<int>(REC_readInteger("proxy.config.diags.action.enabled", &found));
  if (e && found) {
    c.enabled[DiagsTagType_Action] = true; // implement OR logic
  }
  all_found = all_found && found;

  e                     = static_cast<int>(REC_readInteger("proxy.config.diags.show_location", &found));
  _diags->show_location = ((e == 1 && found) ? SHOW_LOCATION_DEBUG : ((e == 2 && found) ? SHOW_LOCATION_ALL : SHOW_LOCATION_NONE));
  all_found             = all_found && found;

  // read output routing values
  for (i = 0;; i++) {
    const char *record_name = output_records[i].config_name;
    DiagsLevel l            = output_records[i].level;

    if (!record_name) {
      break;
    }

    p         = REC_readString(record_name, &found);
    all_found = all_found && found;

    if (found) {
      parse_output_string(p, &(c.outputs[l]));
      ats_free(p);
    } else {
      Error("can't find config variable '%s'", record_name);
    }
  }

  p         = REC_readString("proxy.config.diags.debug.tags", &found);
  dt        = (found ? p : nullptr); // NOTE: needs to be freed
  all_found = all_found && found;

  p         = REC_readString("proxy.config.diags.action.tags", &found);
  at        = (found ? p : nullptr); // NOTE: needs to be freed
  all_found = all_found && found;

  ///////////////////////////////////////////////////////////////////
  // if couldn't read all values, return without changing config,  //
  // otherwise rebuild taglists and change the diags config values //
  ///////////////////////////////////////////////////////////////////

  if (!all_found) {
    Error("couldn't fetch all proxy.config.diags values");
  } else {
    //////////////////////////////
    // clear out old tag tables //
    //////////////////////////////

    _diags->deactivate_all(DiagsTagType_Debug);
    _diags->deactivate_all(DiagsTagType_Action);

    //////////////////////////////////////////////////////////////////////
    // add new tag tables from records.config or command line overrides //
    //////////////////////////////////////////////////////////////////////

    _diags->activate_taglist((_diags->base_debug_tags ? _diags->base_debug_tags : dt), DiagsTagType_Debug);
    _diags->activate_taglist((_diags->base_action_tags ? _diags->base_action_tags : at), DiagsTagType_Action);

////////////////////////////////////
// change the diags config values //
////////////////////////////////////
#if !defined(__GNUC__)
    _diags->config = c;
#else
    memcpy(((void *)&_diags->config), ((void *)&c), sizeof(DiagsConfigState));
#endif
    Note("updated diags config");
  }

  ////////////////////////////////////
  // free the record.config strings //
  ////////////////////////////////////
  ats_free(dt);
  ats_free(at);
}

//////////////////////////////////////////////////////////////////////////////
//
//      static void *diags_config_callback(void *opaque_token, void *data)
//
//      This is the records.config registration callback that is called
//      when any diags value is changed.  Each time a diags value changes
//      the entire diags state is reconfigured.
//
//////////////////////////////////////////////////////////////////////////////
static int
diags_config_callback(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */, RecData /* data ATS_UNUSED */,
                      void *opaque_token)
{
  DiagsConfig *diagsConfig;

  diagsConfig = static_cast<DiagsConfig *>(opaque_token);
  ink_assert(::diags->magic == DIAGS_MAGIC);
  diagsConfig->reconfigure_diags();
  return (0);
}

//////////////////////////////////////////////////////////////////////////////
//
//      void Diags::parse_output_string(char *s, DiagsModeOutput *o)
//
//      This routine converts a diags outpur routing string <s> to the
//      internal DiagsModeOutput structure.  Currently there are 4 possible
//      routing destinations:
//              O  stdout
//              E  stderr
//              S  syslog
//              L  diags.log
//
//////////////////////////////////////////////////////////////////////////////

void
DiagsConfig::parse_output_string(char *s, DiagsModeOutput *o)
{
  o->to_stdout   = (s && strchr(s, 'O'));
  o->to_stderr   = (s && strchr(s, 'E'));
  o->to_syslog   = (s && strchr(s, 'S'));
  o->to_diagslog = (s && strchr(s, 'L'));
}

//////////////////////////////////////////////////////////////////////////////
//
//      void Diags::config_norecords()
//
//      Builds the Diags data structures based on the command line values
//        it does not use any of the records based config variables
//
//////////////////////////////////////////////////////////////////////////////
void
DiagsConfig::config_diags_norecords()
{
  DiagsConfigState c;
  ink_zero(c);

  //////////////////////////////
  // clear out old tag tables //
  //////////////////////////////
  _diags->deactivate_all(DiagsTagType_Debug);
  _diags->deactivate_all(DiagsTagType_Action);

  //////////////////////////////////////////////////////////////////////
  // add new tag tables from command line overrides only              //
  //////////////////////////////////////////////////////////////////////

  if (_diags->base_debug_tags) {
    _diags->activate_taglist(_diags->base_debug_tags, DiagsTagType_Debug);
    c.enabled[DiagsTagType_Debug] = true;
  } else {
    c.enabled[DiagsTagType_Debug] = false;
  }

  if (_diags->base_action_tags) {
    _diags->activate_taglist(_diags->base_action_tags, DiagsTagType_Action);
    c.enabled[DiagsTagType_Action] = true;
  } else {
    c.enabled[DiagsTagType_Action] = false;
  }

#if !defined(__GNUC__)
  _diags->config = c;
#else
  memcpy(((void *)&_diags->config), ((void *)&c), sizeof(DiagsConfigState));
#endif
}

DiagsConfig::DiagsConfig(std::string_view prefix_string, const char *filename, const char *tags, const char *actions,
                         bool use_records)
  : callbacks_established(false), diags_log(nullptr), _diags(nullptr)
{
  char diags_logpath[PATH_NAME_MAX];
  ats_scoped_str logpath;

  ////////////////////////////////////////////////////////////////////
  //  If we aren't using the manager records for configuration      //
  //   just build the tables based on command line parameters and   //
  //   exit                                                         //
  ////////////////////////////////////////////////////////////////////

  if (!use_records) {
    _diags  = new Diags(prefix_string, tags, actions, nullptr);
    ::diags = _diags;
    config_diags_norecords();
    return;
  }

  // Open the diagnostics log. If proxy.config.log.logfile_dir is set use that, otherwise fall
  // back to the configured log directory.

  logpath = RecConfigReadLogDir();
  if (access(logpath, W_OK | R_OK) == -1) {
    fprintf(stderr, "unable to access log directory '%s': %d, %s\n", (const char *)logpath, errno, strerror(errno));
    fprintf(stderr, "please set 'proxy.config.log.logfile_dir'\n");
    ::exit(1);
  }

  ink_filepath_make(diags_logpath, sizeof(diags_logpath), logpath, filename);

  // Grab rolling intervals from configuration
  // TODO error check these values
  int output_log_roll_int    = static_cast<int>(REC_ConfigReadInteger("proxy.config.output.logfile.rolling_interval_sec"));
  int output_log_roll_size   = static_cast<int>(REC_ConfigReadInteger("proxy.config.output.logfile.rolling_size_mb"));
  int output_log_roll_enable = static_cast<int>(REC_ConfigReadInteger("proxy.config.output.logfile.rolling_enabled"));
  int diags_log_roll_int     = static_cast<int>(REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_interval_sec"));
  int diags_log_roll_size    = static_cast<int>(REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_size_mb"));
  int diags_log_roll_enable  = static_cast<int>(REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_enabled"));

  // Grab some perms for the actual files on disk
  char *diags_perm       = REC_ConfigReadString("proxy.config.diags.logfile_perm");
  char *output_perm      = REC_ConfigReadString("proxy.config.output.logfile_perm");
  int diags_perm_parsed  = diags_perm ? ink_fileperm_parse(diags_perm) : -1;
  int output_perm_parsed = diags_perm ? ink_fileperm_parse(output_perm) : -1;

  ats_free(diags_perm);
  ats_free(output_perm);

  // Set up diags, FILE streams are opened in Diags constructor
  diags_log = new BaseLogFile(diags_logpath);
  _diags    = new Diags(prefix_string, tags, actions, diags_log, diags_perm_parsed, output_perm_parsed);
  ::diags   = _diags;
  _diags->config_roll_diagslog(static_cast<RollingEnabledValues>(diags_log_roll_enable), diags_log_roll_int, diags_log_roll_size);
  _diags->config_roll_outputlog(static_cast<RollingEnabledValues>(output_log_roll_enable), output_log_roll_int,
                                output_log_roll_size);

  Status("opened %s", diags_logpath);

  register_diags_callbacks();

  reconfigure_diags();
}

//////////////////////////////////////////////////////////////////////////////
//
//      void DiagsConfig::register_diags_callbacks()
//
//      set up management callbacks to update diags on every change ---   //
//      right now, this system kind of sucks, we rebuild the tag tables //
//      from scratch for *every* proxy.config.diags value that changed; //
//      dgourley is looking into changing the management API to provide //
//      a callback each time records.config changed, possibly better.   //
//
//////////////////////////////////////////////////////////////////////////////
void
DiagsConfig::register_diags_callbacks()
{
  static const char *config_record_names[] = {
    "proxy.config.diags.debug.enabled",  "proxy.config.diags.debug.tags",       "proxy.config.diags.action.enabled",
    "proxy.config.diags.action.tags",    "proxy.config.diags.show_location",    "proxy.config.diags.output.diag",
    "proxy.config.diags.output.debug",   "proxy.config.diags.output.status",    "proxy.config.diags.output.note",
    "proxy.config.diags.output.warning", "proxy.config.diags.output.error",     "proxy.config.diags.output.fatal",
    "proxy.config.diags.output.alert",   "proxy.config.diags.output.emergency", nullptr,
  };

  bool total_status = true;
  bool status;
  int i;
  void *o = (void *)this;

  // set triggers to call same callback for any diag config change
  for (i = 0; config_record_names[i] != nullptr; i++) {
    status = (REC_RegisterConfigUpdateFunc(config_record_names[i], diags_config_callback, o) == REC_ERR_OKAY);
    if (!status) {
      Warning("couldn't register variable '%s', is %s up to date?", config_record_names[i], ts::filename::RECORDS);
    }
    total_status = total_status && status;
  }

  if (total_status == false) {
    Error("couldn't setup all diags callbacks, diagnostics may misbehave");
    callbacks_established = false;
  } else {
    callbacks_established = true;
  }
}

DiagsConfig::~DiagsConfig()
{
  delete _diags;
}
