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

void MaybeAppendPdfiumPathInChromiumCheckout(std::string& path) {
#ifdef BUILD_WITH_CHROMIUM
  path.append("third_party");
  path.push_back(PATH_SEPARATOR);
  path.append("pdfium");
  path.push_back(PATH_SEPARATOR);
#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);
  }

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

  return path;
}

// 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);
  }

  MaybeAppendPdfiumPathInChromiumCheckout(path);
  path.append("third_party");
  if (!PathService::DirectoryExists(path)) {
    return std::string();
  }

  path.push_back(PATH_SEPARATOR);
  path.append(file_name);
  return path;
}
