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

// The "srcs_for_embedded_tools" rule in the same package sets the line below to
// include runfiles.h from the correct path. Do not modify the line below.
#include "tools/cpp/runfiles/runfiles_src.h"

#ifdef _WIN32
#include <windows.h>
#else  // not _WIN32
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif  // _WIN32

#include <algorithm>
#include <fstream>
#include <functional>
#include <map>
#include <sstream>
#include <vector>

#ifdef _WIN32
#include <memory>
#endif  // _WIN32

namespace bazel {
namespace tools {
namespace cpp {
namespace runfiles {

using std::function;
using std::map;
using std::pair;
using std::string;
using std::vector;

namespace {

bool starts_with(const string& s, const char* prefix) {
  if (!prefix || !*prefix) {
    return true;
  }
  if (s.empty()) {
    return false;
  }
  return s.find(prefix) == 0;
}

bool contains(const string& s, const char* substr) {
  if (!substr || !*substr) {
    return true;
  }
  if (s.empty()) {
    return false;
  }
  return s.find(substr) != string::npos;
}

bool ends_with(const string& s, const string& suffix) {
  if (suffix.empty()) {
    return true;
  }
  if (s.empty()) {
    return false;
  }
  return s.rfind(suffix) == s.size() - suffix.size();
}

bool IsReadableFile(const string& path) {
  return std::ifstream(path).is_open();
}

bool IsDirectory(const string& path) {
#ifdef _WIN32
  DWORD attrs = GetFileAttributesA(path.c_str());
  return (attrs != INVALID_FILE_ATTRIBUTES) &&
         (attrs & FILE_ATTRIBUTE_DIRECTORY);
#else
  struct stat buf;
  return stat(path.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode);
#endif
}

bool PathsFrom(const std::string& argv0, std::string runfiles_manifest_file,
               std::string runfiles_dir, std::string* out_manifest,
               std::string* out_directory, std::string* out_repo_mapping);

bool PathsFrom(const std::string& argv0, std::string runfiles_manifest_file,
               std::string runfiles_dir,
               std::function<bool(const std::string&)> is_runfiles_manifest,
               std::function<bool(const std::string&)> is_runfiles_directory,
               std::function<bool(const std::string&)> is_repo_mapping,
               std::string* out_manifest, std::string* out_directory,
               std::string* out_repo_mapping);

bool ParseManifest(const string& path, map<string, string>* result,
                   string* error);
bool ParseRepoMapping(const string& path,
                      map<pair<string, string>, string>* result, string* error);

}  // namespace

Runfiles* Runfiles::Create(const string& argv0,
                           const string& runfiles_manifest_file,
                           const string& runfiles_dir,
                           const string& source_repository, string* error) {
  string manifest, directory, repo_mapping;
  if (!PathsFrom(argv0, runfiles_manifest_file, runfiles_dir, &manifest,
                 &directory, &repo_mapping)) {
    if (error) {
      std::ostringstream err;
      err << "ERROR: " << __FILE__ << "(" << __LINE__
          << "): cannot find runfiles (argv0=\"" << argv0 << "\")";
      *error = err.str();
    }
    return nullptr;
  }

  vector<pair<string, string> > envvars = {
      {"RUNFILES_MANIFEST_FILE", manifest},
      {"RUNFILES_DIR", directory},
      // TODO(laszlocsomor): remove JAVA_RUNFILES once the Java launcher can
      // pick up RUNFILES_DIR.
      {"JAVA_RUNFILES", directory}};

  map<string, string> runfiles;
  if (!manifest.empty()) {
    if (!ParseManifest(manifest, &runfiles, error)) {
      return nullptr;
    }
  }

  map<pair<string, string>, string> mapping;
  if (!repo_mapping.empty()) {
    if (!ParseRepoMapping(repo_mapping, &mapping, error)) {
      return nullptr;
    }
  }

  return new Runfiles(std::move(runfiles), std::move(directory),
                      std::move(mapping), std::move(envvars),
                      string(source_repository));
}

bool IsAbsolute(const string& path) {
  if (path.empty()) {
    return false;
  }
  char c = path.front();
  return (c == '/' && (path.size() < 2 || path[1] != '/')) ||
         (path.size() >= 3 &&
          ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) &&
          path[1] == ':' && (path[2] == '\\' || path[2] == '/'));
}

string GetEnv(const string& key) {
#ifdef _WIN32
  DWORD size = ::GetEnvironmentVariableA(key.c_str(), nullptr, 0);
  if (size == 0) {
    return string();  // unset or empty envvar
  }
  std::unique_ptr<char[]> value(new char[size]);
  ::GetEnvironmentVariableA(key.c_str(), value.get(), size);
  return value.get();
#else
  char* result = getenv(key.c_str());
  return (result == nullptr) ? string() : string(result);
#endif
}

string Runfiles::Rlocation(const string& path) const {
  return Rlocation(path, source_repository_);
}

string Runfiles::Rlocation(const string& path,
                           const string& source_repo) const {
  if (path.empty() || starts_with(path, "../") || contains(path, "/..") ||
      starts_with(path, "./") || contains(path, "/./") ||
      ends_with(path, "/.") || contains(path, "//")) {
    return string();
  }
  if (IsAbsolute(path)) {
    return path;
  }

  if (repo_mapping_.empty()) {
    return RlocationUnchecked(path);
  }
  string::size_type first_slash = path.find_first_of('/');
  if (first_slash == string::npos) {
    return RlocationUnchecked(path);
  }
  string target_apparent = path.substr(0, first_slash);
  auto target =
      repo_mapping_.find(std::make_pair(source_repo, target_apparent));
  if (target == repo_mapping_.cend()) {
    return RlocationUnchecked(path);
  }
  return RlocationUnchecked(target->second + path.substr(first_slash));
}

string Runfiles::RlocationUnchecked(const string& path) const {
  const auto exact_match = runfiles_map_.find(path);
  if (exact_match != runfiles_map_.end()) {
    return exact_match->second;
  }
  if (!runfiles_map_.empty()) {
    // If path references a runfile that lies under a directory that itself is a
    // runfile, then only the directory is listed in the manifest. Look up all
    // prefixes of path in the manifest and append the relative path from the
    // prefix to the looked up path.
    std::size_t prefix_end = path.size();
    while ((prefix_end = path.find_last_of('/', prefix_end - 1)) !=
           string::npos) {
      const string prefix = path.substr(0, prefix_end);
      const auto prefix_match = runfiles_map_.find(prefix);
      if (prefix_match != runfiles_map_.end()) {
        return prefix_match->second + "/" + path.substr(prefix_end + 1);
      }
    }
  }
  if (!directory_.empty()) {
    return directory_ + "/" + path;
  }
  return "";
}

namespace {

bool ParseManifest(const string& path, map<string, string>* result,
                   string* error) {
  std::ifstream stm(path);
  if (!stm.is_open()) {
    if (error) {
      std::ostringstream err;
      err << "ERROR: " << __FILE__ << "(" << __LINE__
          << "): cannot open runfiles manifest \"" << path << "\"";
      *error = err.str();
    }
    return false;
  }
  string line;
  std::getline(stm, line);
  size_t line_count = 1;
  while (!line.empty()) {
    string::size_type idx = line.find_first_of(' ');
    if (idx == string::npos) {
      if (error) {
        std::ostringstream err;
        err << "ERROR: " << __FILE__ << "(" << __LINE__
            << "): bad runfiles manifest entry in \"" << path << "\" line #"
            << line_count << ": \"" << line << "\"";
        *error = err.str();
      }
      return false;
    }
    (*result)[line.substr(0, idx)] = line.substr(idx + 1);
    std::getline(stm, line);
    ++line_count;
  }
  return true;
}

bool ParseRepoMapping(const string& path,
                      map<pair<string, string>, string>* result,
                      string* error) {
  std::ifstream stm(path);
  if (!stm.is_open()) {
    if (error) {
      std::ostringstream err;
      err << "ERROR: " << __FILE__ << "(" << __LINE__
          << "): cannot open repository mapping \"" << path << "\"";
      *error = err.str();
    }
    return false;
  }
  string line;
  std::getline(stm, line);
  size_t line_count = 1;
  while (!line.empty()) {
    string::size_type first_comma = line.find_first_of(',');
    if (first_comma == string::npos) {
      if (error) {
        std::ostringstream err;
        err << "ERROR: " << __FILE__ << "(" << __LINE__
            << "): bad repository mapping entry in \"" << path << "\" line #"
            << line_count << ": \"" << line << "\"";
        *error = err.str();
      }
      return false;
    }
    string::size_type second_comma = line.find_first_of(',', first_comma + 1);
    if (second_comma == string::npos) {
      if (error) {
        std::ostringstream err;
        err << "ERROR: " << __FILE__ << "(" << __LINE__
            << "): bad repository mapping entry in \"" << path << "\" line #"
            << line_count << ": \"" << line << "\"";
        *error = err.str();
      }
      return false;
    }

    string source = line.substr(0, first_comma);
    string target_apparent =
        line.substr(first_comma + 1, second_comma - (first_comma + 1));
    string target = line.substr(second_comma + 1);

    (*result)[std::make_pair(source, target_apparent)] = target;
    std::getline(stm, line);
    ++line_count;
  }
  return true;
}

}  // namespace

namespace testing {

bool TestOnly_PathsFrom(const string& argv0, string mf, string dir,
                        function<bool(const string&)> is_runfiles_manifest,
                        function<bool(const string&)> is_runfiles_directory,
                        function<bool(const string&)> is_repo_mapping,
                        string* out_manifest, string* out_directory,
                        string* out_repo_mapping) {
  return PathsFrom(argv0, mf, dir, is_runfiles_manifest, is_runfiles_directory,
                   is_repo_mapping, out_manifest, out_directory,
                   out_repo_mapping);
}

bool TestOnly_IsAbsolute(const string& path) { return IsAbsolute(path); }

}  // namespace testing

Runfiles* Runfiles::Create(const std::string& argv0,
                           const std::string& runfiles_manifest_file,
                           const std::string& runfiles_dir,
                           std::string* error) {
  return Runfiles::Create(argv0, runfiles_manifest_file, runfiles_dir, "",
                          error);
}

Runfiles* Runfiles::Create(const string& argv0, const string& source_repository,
                           string* error) {
  return Runfiles::Create(argv0, GetEnv("RUNFILES_MANIFEST_FILE"),
                          GetEnv("RUNFILES_DIR"), source_repository, error);
}

Runfiles* Runfiles::Create(const string& argv0, string* error) {
  return Runfiles::Create(argv0, "", error);
}

Runfiles* Runfiles::CreateForTest(const string& source_repository,
                                  std::string* error) {
  return Runfiles::Create(std::string(), GetEnv("RUNFILES_MANIFEST_FILE"),
                          GetEnv("TEST_SRCDIR"), source_repository, error);
}

Runfiles* Runfiles::CreateForTest(std::string* error) {
  return Runfiles::CreateForTest("", error);
}

namespace {

bool PathsFrom(const string& argv0, string mf, string dir, string* out_manifest,
               string* out_directory, string* out_repo_mapping) {
  return PathsFrom(
      argv0, mf, dir, [](const string& path) { return IsReadableFile(path); },
      [](const string& path) { return IsDirectory(path); },
      [](const string& path) { return IsReadableFile(path); }, out_manifest,
      out_directory, out_repo_mapping);
}

bool PathsFrom(const string& argv0, string mf, string dir,
               function<bool(const string&)> is_runfiles_manifest,
               function<bool(const string&)> is_runfiles_directory,
               function<bool(const string&)> is_repo_mapping,
               string* out_manifest, string* out_directory,
               string* out_repo_mapping) {
  out_manifest->clear();
  out_directory->clear();
  out_repo_mapping->clear();

  bool mfValid = is_runfiles_manifest(mf);
  bool dirValid = is_runfiles_directory(dir);

  if (!argv0.empty() && !mfValid && !dirValid) {
    mf = argv0 + ".runfiles/MANIFEST";
    dir = argv0 + ".runfiles";
    mfValid = is_runfiles_manifest(mf);
    dirValid = is_runfiles_directory(dir);
    if (!mfValid) {
      mf = argv0 + ".runfiles_manifest";
      mfValid = is_runfiles_manifest(mf);
    }
  }

  if (!mfValid && !dirValid) {
    return false;
  }

  if (!mfValid) {
    mf = dir + "/MANIFEST";
    mfValid = is_runfiles_manifest(mf);
    if (!mfValid) {
      mf = dir + "_manifest";
      mfValid = is_runfiles_manifest(mf);
    }
  }

  if (!dirValid &&
      (ends_with(mf, ".runfiles_manifest") || ends_with(mf, "/MANIFEST"))) {
    static const size_t kSubstrLen = 9;  // "_manifest" or "/MANIFEST"
    dir = mf.substr(0, mf.size() - kSubstrLen);
    dirValid = is_runfiles_directory(dir);
  }

  string rm;
  bool rmValid = false;

  if (dirValid && ends_with(dir, ".runfiles")) {
    rm = dir.substr(0, dir.size() - 9) + ".repo_mapping";
    rmValid = is_repo_mapping(rm);
  }

  if (!rmValid && mfValid &&
      (ends_with(mf, ".runfiles_manifest") ||
       ends_with(mf, ".runfiles/MANIFEST"))) {
    rm = mf.substr(0, mf.size() - 18) + ".repo_mapping";
    rmValid = is_repo_mapping(rm);
  }

  if (mfValid) {
    *out_manifest = mf;
  }

  if (dirValid) {
    *out_directory = dir;
  }

  if (rmValid) {
    *out_repo_mapping = rm;
  }

  return true;
}

}  // namespace

}  // namespace runfiles
}  // namespace cpp
}  // namespace tools
}  // namespace bazel
