// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed 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 "src/main/cpp/util/path_platform.h"

#include <limits.h>  // PATH_MAX

#include <stdlib.h>  // getenv
#include <string.h>  // strncmp
#include <unistd.h>  // access, open, close, fsync
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/path.h"

namespace blaze_util {

std::string ConvertPath(const std::string &path) { return path; }

std::string PathAsJvmFlag(const std::string &path) { return path; }

bool CompareAbsolutePaths(const std::string &a, const std::string &b) {
  return a == b;
}

std::pair<std::string, std::string> SplitPath(const std::string &path) {
  size_t pos = path.rfind('/');

  // Handle the case with no '/' in 'path'.
  if (pos == std::string::npos) return std::make_pair("", path);

  // Handle the case with a single leading '/' in 'path'.
  if (pos == 0)
    return std::make_pair(std::string(path, 0, 1), std::string(path, 1));

  return std::make_pair(std::string(path, 0, pos), std::string(path, pos + 1));
}

bool IsDevNull(const char *path) {
  return path != NULL && *path != 0 && strncmp("/dev/null\0", path, 10) == 0;
}

bool IsRootDirectory(const std::string &path) {
  return path.size() == 1 && path[0] == '/';
}

bool IsAbsolute(const std::string &path) {
  return !path.empty() && path[0] == '/';
}

std::string MakeAbsolute(const std::string &path) {
  if (blaze_util::IsAbsolute(path) || path.empty()) {
    return path;
  }

  return JoinPath(blaze_util::GetCwd(), path);
}

std::string ResolveEnvvars(const std::string &path) {
  std::string result = path;
  size_t start = 0;
  while ((start = result.find("${", start)) != std::string::npos) {
    // Just match to the next }
    size_t end = result.find("}", start + 1);
    if (end == std::string::npos) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "ResolveEnvvars(" << path << "): incomplete variable at position "
          << start;
    }
    // Extract the variable name
    const std::string name = result.substr(start + 2, end - start - 2);
    // Get the value from the environment
    const char *c_value = getenv(name.c_str());
    const std::string value = std::string(c_value ? c_value : "");
    result.replace(start, end - start + 1, value);
    start += value.length();
  }
  return result;
}

std::string MakeAbsoluteAndResolveEnvvars(const std::string &path) {
  return MakeAbsolute(ResolveEnvvars(path));
}

static std::string NormalizeAbsPath(const std::string &p) {
  if (p.empty() || p[0] != '/') {
    return "";
  }
  typedef std::string::size_type index;
  std::vector<std::pair<index, index> > segments;
  for (index s = 0; s < p.size();) {
    index e = p.find_first_of('/', s);
    if (e == std::string::npos) {
      e = p.size();
    }
    if (e > s) {
      if (p.compare(s, e - s, "..") == 0) {
        if (!segments.empty()) {
          segments.pop_back();
        }
      } else if (p.compare(s, e - s, ".") != 0) {
        segments.push_back(std::make_pair(s, e - s));
      }
    }
    s = e + 1;
  }
  if (segments.empty()) {
    return "/";
  } else {
    std::stringstream r;
    for (const auto &s : segments) {
      r << "/" << p.substr(s.first, s.second);
    }
    if (p[p.size() - 1] == '/') {
      r << "/";
    }
    return r.str();
  }
}

std::string TestOnly_NormalizeAbsPath(const std::string &s) {
  return NormalizeAbsPath(s);
}

Path::Path(const std::string &path)
    : path_(NormalizeAbsPath(MakeAbsolute(path))) {}

bool Path::IsNull() const { return path_ == "/dev/null"; }

bool Path::Contains(const char c) const {
  return path_.find_first_of(c) != std::string::npos;
}

bool Path::Contains(const std::string &s) const {
  return path_.find(s) != std::string::npos;
}

Path Path::GetRelative(const std::string &r) const {
  return Path(JoinPath(path_, r));
}

Path Path::Canonicalize() const { return Path(MakeCanonical(path_.c_str())); }

Path Path::GetParent() const { return Path(SplitPath(path_).first); }

std::string Path::AsPrintablePath() const { return path_; }

std::string Path::AsJvmArgument() const { return path_; }

std::string Path::AsCommandLineArgument() const { return path_; }

}  // namespace blaze_util
