// Copyright 2015 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "testing/utils/path_service.h"

#include <stddef.h>

#ifdef _WIN32
#include <Windows.h>
#elif defined(__APPLE__)
#include <mach-o/dyld.h>
#include <sys/stat.h>
#else  // Linux
#include <linux/limits.h>
#include <sys/stat.h>
#include <unistd.h>
#endif  // _WIN32

#include <string>

#include "core/fxcrt/check.h"
#include "core/fxcrt/fx_system.h"

namespace {

#if defined(__APPLE__) || (defined(ANDROID) && __ANDROID_API__ < 21)
using stat_wrapper_t = struct stat;

int CallStat(const char* path, stat_wrapper_t* sb) {
  return stat(path, sb);
}
#elif !_WIN32
using stat_wrapper_t = struct stat64;

int CallStat(const char* path, stat_wrapper_t* sb) {
  return stat64(path, sb);
}
#endif

}  // namespace

// static
bool PathService::DirectoryExists(const std::string& path) {
#ifdef _WIN32
  DWORD fileattr = GetFileAttributesA(path.c_str());
  if (fileattr != INVALID_FILE_ATTRIBUTES) {
    return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
  }
  return false;
#else
  stat_wrapper_t file_info;
  if (CallStat(path.c_str(), &file_info) != 0) {
    return false;
  }
  return S_ISDIR(file_info.st_mode);
#endif
}

// static
bool PathService::EndsWithSeparator(const std::string& path) {
  return path.size() > 1 && path[path.size() - 1] == PATH_SEPARATOR;
}

// static
std::string PathService::GetExecutableDir() {
  std::string path;
// Get the current executable file path.
#ifdef _WIN32
  char path_buffer[MAX_PATH];
  path_buffer[0] = 0;

  if (GetModuleFileNameA(nullptr, path_buffer, MAX_PATH) == 0) {
    return std::string();
  }
  path = std::string(path_buffer);
#elif defined(__APPLE__)
  unsigned int path_length = 0;
  _NSGetExecutablePath(nullptr, &path_length);
  if (path_length == 0) {
    return std::string();
  }

  path.reserve(path_length);
  path.resize(path_length - 1);
  if (_NSGetExecutablePath(&path[0], &path_length)) {
    return std::string();
  }
#else   // Linux
  static const char kProcSelfExe[] = "/proc/self/exe";
  char buf[PATH_MAX];
  ssize_t count = ::readlink(kProcSelfExe, buf, PATH_MAX);
  if (count <= 0) {
    return std::string();
  }

  path = std::string(buf, count);
#endif  // _WIN32

  // Get the directory path.
  size_t pos = path.size() - 1;
  if (EndsWithSeparator(path)) {
    pos--;
  }
  size_t found = path.find_last_of(PATH_SEPARATOR, pos);
  if (found == std::string::npos) {
    return std::string();
  }
  path.resize(found);
  return path;
}

// static
std::string PathService::GetSourceDir() {
  std::string path = GetExecutableDir();
  if (path.empty()) {
    return std::string();
  }

  if (!EndsWithSeparator(path)) {
    path.push_back(PATH_SEPARATOR);
  }
  path.append("..");
  path.push_back(PATH_SEPARATOR);
#if defined(ANDROID)
  path.append("chromium_tests_root");
#else   // Non-Android
  path.append("..");
#endif  // defined(ANDROID)
  return path;
}

// static
std::string PathService::GetTestDataDir() {
  std::string path = GetSourceDir();
  if (path.empty()) {
    return std::string();
  }

  if (!EndsWithSeparator(path)) {
    path.push_back(PATH_SEPARATOR);
  }

  std::string potential_path = path;
  potential_path.append("testing");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("resources");
  if (PathService::DirectoryExists(potential_path)) {
    return potential_path;
  }

  potential_path = path;
  potential_path.append("third_party");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("pdfium");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("testing");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("resources");
  if (PathService::DirectoryExists(potential_path)) {
    return potential_path;
  }

  return std::string();
}

// static
std::string PathService::GetTestFilePath(const std::string& file_name) {
  std::string path = GetTestDataDir();
  if (path.empty()) {
    return std::string();
  }

  if (!EndsWithSeparator(path)) {
    path.push_back(PATH_SEPARATOR);
  }
  path.append(file_name);
  return path;
}

// static
std::string PathService::GetThirdPartyFilePath(const std::string& file_name) {
  std::string path = GetSourceDir();
  if (path.empty()) {
    return std::string();
  }

  if (!EndsWithSeparator(path)) {
    path.push_back(PATH_SEPARATOR);
  }

  std::string potential_path = path;
  potential_path.append("third_party");

  // Use third_party/bigint as a way to distinguish PDFium's vs. other's.
  std::string bigint = potential_path + PATH_SEPARATOR + "bigint";
  if (PathService::DirectoryExists(bigint)) {
    potential_path.append(PATH_SEPARATOR + file_name);
    return potential_path;
  }

  potential_path = path;
  potential_path.append("third_party");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("pdfium");
  potential_path.push_back(PATH_SEPARATOR);
  potential_path.append("third_party");
  bigint = potential_path + PATH_SEPARATOR + "bigint";
  if (PathService::DirectoryExists(potential_path)) {
    potential_path.append(PATH_SEPARATOR + file_name);
    return potential_path;
  }

  return std::string();
}
