// Copyright 2015 PDFium Authors. All rights reserved.
// 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"

#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/fx_system.h"
#include "third_party/base/check.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
bool PathService::GetExecutableDir(std::string* path) {
// Get the current executable file path.
#ifdef _WIN32
  char path_buffer[MAX_PATH];
  path_buffer[0] = 0;

  if (GetModuleFileNameA(NULL, path_buffer, MAX_PATH) == 0)
    return false;
  *path = std::string(path_buffer);
#elif defined(__APPLE__)
  DCHECK(path);
  unsigned int path_length = 0;
  _NSGetExecutablePath(NULL, &path_length);
  if (path_length == 0)
    return false;

  path->reserve(path_length);
  path->resize(path_length - 1);
  if (_NSGetExecutablePath(&((*path)[0]), &path_length))
    return false;
#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 false;

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

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

// static
bool PathService::GetSourceDir(std::string* path) {
  if (!GetExecutableDir(path))
    return false;

  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 true;
}

// static
bool PathService::GetTestDataDir(std::string* path) {
  if (!GetSourceDir(path))
    return false;

  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)) {
    *path = potential_path;
    return true;
  }

  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)) {
    *path = potential_path;
    return true;
  }

  return false;
}

// static
bool PathService::GetTestFilePath(const std::string& file_name,
                                  std::string* path) {
  if (!GetTestDataDir(path))
    return false;

  if (!EndsWithSeparator(*path))
    path->push_back(PATH_SEPARATOR);
  path->append(file_name);
  return true;
}

// static
bool PathService::GetThirdPartyFilePath(const std::string& file_name,
                                        std::string* path) {
  if (!GetSourceDir(path))
    return false;

  if (!EndsWithSeparator(*path))
    path->push_back(PATH_SEPARATOR);

  std::string potential_path = *path;
  potential_path.append("third_party");
  if (PathService::DirectoryExists(potential_path)) {
    *path = potential_path;
    path->append(PATH_SEPARATOR + file_name);
    return true;
  }

  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");
  if (PathService::DirectoryExists(potential_path)) {
    *path = potential_path;
    path->append(PATH_SEPARATOR + file_name);
    return true;
  }

  return false;
}
