/** @file

  runroot.cc

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

/*
  Please refer to traffic_layout document for the usage
*/

#include "tscore/ink_error.h"
#include "tscore/I_Layout.h"
#include "tscore/runroot.h"
#include <yaml-cpp/yaml.h>

static std::string runroot_file = {};

// this is a temporary approach and will be replaced when std::filesystem is in
bool
exists(const std::string &dir)
{
  struct stat buffer;
  int result = stat(dir.c_str(), &buffer);
  return (!result) ? true : false;
}

bool
is_directory(const std::string &directory)
{
  struct stat buffer;
  int result = stat(directory.c_str(), &buffer);
  return (!result && (S_IFDIR & buffer.st_mode)) ? true : false;
}

// the function for the checking of the yaml file in the passed in path
// if found return the path to the yaml file, if not return empty string.
static std::string
get_yaml_path(const std::string &path)
{
  // yaml_file 2 and 3 are for temporary use in case the change may break for people using runroot already
  // this can be removed in the future.
  std::string yaml_file;
  std::string yaml_file2;
  std::string yaml_file3;
  if (is_directory(path.c_str())) {
    std::string yaml_file(Layout::relative_to(path, "runroot.yaml"));
    if (exists(yaml_file)) {
      return yaml_file;
    }
    std::string yaml_file2(Layout::relative_to(path, "runroot.yml"));
    if (exists(yaml_file2)) {
      return yaml_file2;
    }
    std::string yaml_file3(Layout::relative_to(path, "runroot_path.yml"));
    if (exists(yaml_file3)) {
      return yaml_file3;
    }
  } else if (exists(path)) {
    return path;
  }
  return {};
}

// the function for the checking of the yaml file in passed in directory or parent directory
// if found return the parent path to the yaml file
static std::string
get_parent_yaml_path(const std::string &path)
{
  std::string whole_path = path;
  if (whole_path.back() == '/') {
    whole_path.pop_back();
  }
  // go up to 4 level of parent directories
  for (int i = 0; i < 4; i++) {
    if (whole_path.empty()) {
      return {};
    }
    std::string yaml_file = get_yaml_path(whole_path);
    if (!yaml_file.empty()) {
      return yaml_file;
    }
    whole_path = whole_path.substr(0, whole_path.find_last_of('/'));
  }
  return {};
}

static void
runroot_extra_handling(const char *executable, bool json)
{
  std::string path;
  // 2. check Environment variable
  char *env_val = getenv("TS_RUNROOT");
  if (env_val) {
    path = get_yaml_path(env_val);
    if (!path.empty()) {
      runroot_file = path;
      if (!json) {
        ink_notice("using the environment variable TS_RUNROOT");
      }
      return;
    } else if (!json) {
      ink_warning("Unable to access runroot: '%s' from $TS_RUNROOT", env_val);
    }
  }
  // 3. find cwd or parent path of cwd to check
  char cwd[PATH_MAX] = {0};
  if (getcwd(cwd, sizeof(cwd)) != nullptr) {
    path = get_parent_yaml_path(cwd);
    if (!path.empty()) {
      runroot_file = path;
      if (!json) {
        ink_notice("using cwd as TS_RUNROOT");
      }
      return;
    }
  }
  // 4. installed executable
  char RealBinPath[PATH_MAX] = {0};
  if ((executable != nullptr) && realpath(executable, RealBinPath) != nullptr) {
    std::string bindir = RealBinPath;
    bindir             = bindir.substr(0, bindir.find_last_of('/')); // getting the bin dir not executable path
    path               = get_parent_yaml_path(bindir);
    if (!path.empty()) {
      runroot_file = path;
      if (!json) {
        ink_notice("using the installed dir as TS_RUNROOT");
      }
      return;
    }
  }
  // 5. if no runroot use, using default build
  return;
}

// This is a temporary approach to handle runroot with migration to ArgParser.
// When all program use ArgParser, we can remove the runroot_handler below and replace it with this one.
void
argparser_runroot_handler(std::string const &value, const char *executable, bool json)
{
  // 1.if --run-root is provided
  if (!value.empty()) {
    std::string path = get_yaml_path(value);
    if (!path.empty()) {
      if (!json) {
        ink_notice("using command line path as RUNROOT");
      }
      runroot_file = path;
      return;
    } else if (!json) {
      ink_warning("Unable to access runroot: '%s'", value.c_str());
    }
  }
  runroot_extra_handling(executable, json);
}

// handler for ts runroot
// this function set up runroot_file
void
runroot_handler(const char **argv, bool json)
{
  std::string prefix = "--run-root";
  std::string path;

  // check if we have --run-root...
  std::string arg = {};

  int i = 0;
  while (argv[i]) {
    std::string_view command = argv[i];
    if (command.substr(0, prefix.size()) == prefix) {
      arg = command.data();
      break;
    }
    i++;
  }

  // if --run-root is provided
  if (!arg.empty() && arg != prefix) {
    // 1. pass in path
    prefix += "=";
    std::string value = arg.substr(prefix.size(), arg.size() - 1);
    path              = get_yaml_path(value);
    if (!path.empty()) {
      if (!json) {
        ink_notice("using command line path as RUNROOT");
      }
      runroot_file = path;
      return;
    } else if (!json) {
      ink_warning("Unable to access runroot: '%s'", value.c_str());
    }
  }

  runroot_extra_handling(argv[0], json);
}

// return a map of all path with default layout
std::unordered_map<std::string, std::string>
runroot_map_default()
{
  std::unordered_map<std::string, std::string> map;

  map[LAYOUT_PREFIX]        = Layout::get()->prefix;
  map[LAYOUT_EXEC_PREFIX]   = Layout::get()->exec_prefix;
  map[LAYOUT_BINDIR]        = Layout::get()->bindir;
  map[LAYOUT_SBINDIR]       = Layout::get()->sbindir;
  map[LAYOUT_SYSCONFDIR]    = Layout::get()->sysconfdir;
  map[LAYOUT_DATADIR]       = Layout::get()->datadir;
  map[LAYOUT_INCLUDEDIR]    = Layout::get()->includedir;
  map[LAYOUT_LIBDIR]        = Layout::get()->libdir;
  map[LAYOUT_LIBEXECDIR]    = Layout::get()->libexecdir;
  map[LAYOUT_LOCALSTATEDIR] = Layout::get()->localstatedir;
  map[LAYOUT_RUNTIMEDIR]    = Layout::get()->runtimedir;
  map[LAYOUT_LOGDIR]        = Layout::get()->logdir;
  // mandir is not needed for runroot
  map[LAYOUT_CACHEDIR] = Layout::get()->cachedir;

  return map;
}

// return a map of all path in runroot.yaml
RunrootMapType
runroot_map(const std::string &file)
{
  RunrootMapType map;
  try {
    YAML::Node yamlfile = YAML::LoadFile(file);
    std::string prefix  = file.substr(0, file.find_last_of('/'));

    for (const auto &it : yamlfile) {
      // key value pairs of dirs
      std::string value = it.second.as<std::string>();
      if (value[0] != '/') {
        value = Layout::relative_to(prefix, value);
      }
      map[it.first.as<std::string>()] = value;
    }
  } catch (YAML::Exception &e) {
    ink_warning("Unable to read '%s': %s", file.c_str(), e.what());
    ink_notice("Continuing with default value");
    return RunrootMapType{};
  }
  return map;
}

// check for the using of runroot
// a map of all path will be returned
// if we do not use runroot, a empty map will be returned.
RunrootMapType
check_runroot()
{
  if (runroot_file.empty()) {
    return RunrootMapType{};
  }

  int len = runroot_file.size();
  if ((len + 1) > PATH_NAME_MAX) {
    ink_fatal("runroot path is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
  }
  return runroot_map(runroot_file);
}

std::string_view
get_runroot()
{
  return runroot_file;
}
