/** @file

  Implementation of the Layout class.

  @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_assert.h"
#include "tscore/ink_file.h"
#include "tscore/ink_memory.h"
#include "tscore/ink_string.h"
#include "tscore/I_Layout.h"
#include "tscore/runroot.h"

#include <unordered_map>

static Layout *layout = nullptr;

Layout *
Layout::get()
{
  if (layout == nullptr) {
    ink_assert("need to call create_default_layout before accessing"
               "default_layout()");
  }
  return layout;
}

void
Layout::create(std::string_view const prefix)
{
  if (layout == nullptr) {
    layout = new Layout(prefix);
  }
}

static void
_relative(char *path, size_t buffsz, std::string_view root, std::string_view file)
{
  if (ink_filepath_merge(path, buffsz, root.data(), file.data(), INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_fatal("Cannot merge path '%s' above the root '%s'\n", file.data(), root.data());
    } else if (err == E2BIG) {
      ink_fatal("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
    } else {
      // TODO: Make some pretty errors.
      ink_fatal("Cannot merge '%s' with '%s' error=%d\n", file.data(), root.data(), err);
    }
  }
}

static std::string
layout_relative(std::string_view root, std::string_view file)
{
  char path[PATH_NAME_MAX];
  std::string ret;
  _relative(path, PATH_NAME_MAX, root, file);
  ret = path;
  return ret;
}

std::string
Layout::relative(std::string_view file)
{
  return layout_relative(prefix, file);
}

// for updating the structure sysconfdir
void
Layout::update_sysconfdir(std::string_view dir)
{
  sysconfdir.assign(dir.data(), dir.size());
}

std::string
Layout::relative_to(std::string_view dir, std::string_view file)
{
  return layout_relative(dir, file);
}

void
Layout::relative_to(char *buf, size_t bufsz, std::string_view dir, std::string_view file)
{
  char path[PATH_NAME_MAX];

  _relative(path, PATH_NAME_MAX, dir, file);
  size_t path_len = strlen(path) + 1;
  if (path_len > bufsz) {
    ink_fatal("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
  } else {
    ink_strlcpy(buf, path, bufsz);
  }
}

bool
Layout::runroot_setup()
{
  std::string runroot_file = get_runroot().data();
  if (runroot_file.empty()) {
    // runroot is not used
    return false;
  }
  RunrootMapType dir_map = check_runroot();
  if (dir_map.empty()) {
    ink_warning("No value provided in runroot.yaml\n");
  }
  // If some path values are not in runroot.yaml, we give it a default value instead of error out.
  prefix      = dir_map[LAYOUT_PREFIX].empty() ? runroot_file.substr(0, runroot_file.find_last_of('/')) : dir_map[LAYOUT_PREFIX];
  exec_prefix = dir_map[LAYOUT_EXEC_PREFIX].empty() ? prefix : dir_map[LAYOUT_EXEC_PREFIX];
  bindir = dir_map[LAYOUT_BINDIR].empty() ? layout_relative(prefix, TS_BUILD_BINDIR) : bindir = dir_map[LAYOUT_BINDIR];
  sbindir    = dir_map[LAYOUT_SBINDIR].empty() ? layout_relative(prefix, TS_BUILD_SBINDIR) : dir_map[LAYOUT_SBINDIR];
  sysconfdir = dir_map[LAYOUT_SYSCONFDIR].empty() ? layout_relative(prefix, TS_BUILD_SYSCONFDIR) : dir_map[LAYOUT_SYSCONFDIR];
  datadir    = dir_map[LAYOUT_DATADIR].empty() ? layout_relative(prefix, TS_BUILD_DATADIR) : dir_map[LAYOUT_DATADIR];
  includedir = dir_map[LAYOUT_INCLUDEDIR].empty() ? layout_relative(prefix, TS_BUILD_INCLUDEDIR) : dir_map[LAYOUT_INCLUDEDIR];
  libdir     = dir_map[LAYOUT_LIBDIR].empty() ? layout_relative(prefix, TS_BUILD_LIBDIR) : dir_map[LAYOUT_LIBDIR];
  libexecdir = dir_map[LAYOUT_LIBEXECDIR].empty() ? layout_relative(prefix, TS_BUILD_LIBEXECDIR) : dir_map[LAYOUT_LIBEXECDIR];
  localstatedir =
    dir_map[LAYOUT_LOCALSTATEDIR].empty() ? layout_relative(prefix, TS_BUILD_LOCALSTATEDIR) : dir_map[LAYOUT_LOCALSTATEDIR];
  runtimedir = dir_map[LAYOUT_RUNTIMEDIR].empty() ? layout_relative(prefix, TS_BUILD_RUNTIMEDIR) : dir_map[LAYOUT_RUNTIMEDIR];
  logdir     = dir_map[LAYOUT_LOGDIR].empty() ? layout_relative(prefix, TS_BUILD_LOGDIR) : dir_map[LAYOUT_LOGDIR];
  mandir     = dir_map[LAYOUT_MANDIR].empty() ? layout_relative(prefix, TS_BUILD_MANDIR) : dir_map[LAYOUT_MANDIR];
  infodir    = dir_map[LAYOUT_INFODIR].empty() ? layout_relative(prefix, TS_BUILD_INFODIR) : dir_map[LAYOUT_INFODIR];
  cachedir   = dir_map[LAYOUT_CACHEDIR].empty() ? layout_relative(prefix, TS_BUILD_CACHEDIR) : dir_map[LAYOUT_CACHEDIR];
  return true;
}

Layout::Layout(std::string_view const _prefix)
{
  // if runroot is used, we set it up directly
  if (runroot_setup()) {
    return;
  }
  if (!_prefix.empty()) {
    prefix.assign(_prefix.data(), _prefix.size());
  } else {
    std::string path;
    int len;
    if (getenv("TS_ROOT") != nullptr) {
      std::string env_path(getenv("TS_ROOT"));
      len = env_path.size();
      if ((len + 1) > PATH_NAME_MAX) {
        ink_fatal("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
      }
      path = env_path;
      while (path.back() == '/') {
        path.pop_back();
      }
    } else {
      // Use compile time --prefix
      path = TS_BUILD_PREFIX;
    }
    prefix = path;
  }
  exec_prefix   = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
  bindir        = layout_relative(prefix, TS_BUILD_BINDIR);
  sbindir       = layout_relative(prefix, TS_BUILD_SBINDIR);
  sysconfdir    = layout_relative(prefix, TS_BUILD_SYSCONFDIR);
  datadir       = layout_relative(prefix, TS_BUILD_DATADIR);
  includedir    = layout_relative(prefix, TS_BUILD_INCLUDEDIR);
  libdir        = layout_relative(prefix, TS_BUILD_LIBDIR);
  libexecdir    = layout_relative(prefix, TS_BUILD_LIBEXECDIR);
  localstatedir = layout_relative(prefix, TS_BUILD_LOCALSTATEDIR);
  runtimedir    = layout_relative(prefix, TS_BUILD_RUNTIMEDIR);
  logdir        = layout_relative(prefix, TS_BUILD_LOGDIR);
  mandir        = layout_relative(prefix, TS_BUILD_MANDIR);
  infodir       = layout_relative(prefix, TS_BUILD_INFODIR);
  cachedir      = layout_relative(prefix, TS_BUILD_CACHEDIR);
}

Layout::~Layout() {}
