/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/testsupport/file_utils.h"

#if defined(WEBRTC_POSIX)
#include <unistd.h>
#endif

#if defined(WEBRTC_WIN)
#include <direct.h>
#include <tchar.h>
#include <windows.h>

#include <algorithm>
#include <locale>

#include "Shlwapi.h"
#include "WinDef.h"
#include "rtc_base/win32.h"

#define GET_CURRENT_DIR _getcwd
#else
#include <dirent.h>

#define GET_CURRENT_DIR getcwd
#endif

#include <sys/stat.h>  // To check for directory existence.
#ifndef S_ISDIR        // Not defined in stat.h on Windows.
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif

#include <stdio.h>
#include <stdlib.h>

#include <memory>
#include <type_traits>
#include <utility>

#if defined(WEBRTC_IOS)
#include "test/testsupport/ios_file_utils.h"
#elif defined(WEBRTC_MAC)
#include "test/testsupport/mac_file_utils.h"
#endif

#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/crypto_random.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/strings/string_builder.h"
#include "test/testsupport/file_utils_override.h"

namespace webrtc {
namespace test {

#if defined(WEBRTC_WIN)
ABSL_CONST_INIT const absl::string_view kPathDelimiter = "\\";
#else
ABSL_CONST_INIT const absl::string_view kPathDelimiter = "/";
#endif

std::string DirName(absl::string_view path) {
  if (path.empty())
    return "";
  if (path == kPathDelimiter)
    return std::string(path);

  if (path.back() == kPathDelimiter[0])
    path.remove_suffix(1);  // Remove trailing separator.

  return std::string(path.substr(0, path.find_last_of(kPathDelimiter)));
}

bool FileExists(absl::string_view file_name) {
  struct stat file_info = {0};
  return stat(std::string(file_name).c_str(), &file_info) == 0;
}

bool DirExists(absl::string_view directory_name) {
  struct stat directory_info = {0};
  return stat(std::string(directory_name).c_str(), &directory_info) == 0 &&
         S_ISDIR(directory_info.st_mode);
}

std::string OutputPath() {
  return webrtc::test::internal::OutputPath();
}

std::string OutputPathWithRandomDirectory() {
  std::string path = webrtc::test::internal::OutputPath();
  std::string rand_dir = path + rtc::CreateRandomUuid();

  return CreateDir(rand_dir) ? rand_dir + std::string(kPathDelimiter) : path;
}

std::string WorkingDir() {
  return webrtc::test::internal::WorkingDir();
}

// Generate a temporary filename in a safe way.
// Largely copied from talk/base/{unixfilesystem,win32filesystem}.cc.
std::string TempFilename(absl::string_view dir, absl::string_view prefix) {
#ifdef WIN32
  wchar_t filename[MAX_PATH];
  if (::GetTempFileNameW(rtc::ToUtf16(dir).c_str(),
                         rtc::ToUtf16(prefix).c_str(), 0, filename) != 0)
    return rtc::ToUtf8(filename);
  RTC_DCHECK_NOTREACHED();
  return "";
#else
  rtc::StringBuilder os;
  os << dir << "/" << prefix << "XXXXXX";
  std::string tempname = os.Release();

  int fd = ::mkstemp(tempname.data());
  if (fd == -1) {
    RTC_DCHECK_NOTREACHED();
    return "";
  } else {
    ::close(fd);
  }
  return tempname;
#endif
}

std::string GenerateTempFilename(absl::string_view dir,
                                 absl::string_view prefix) {
  std::string filename = TempFilename(dir, prefix);
  RemoveFile(filename);
  return filename;
}

absl::optional<std::vector<std::string>> ReadDirectory(absl::string_view path) {
  if (path.length() == 0)
    return absl::optional<std::vector<std::string>>();

  std::string path_str(path);

#if defined(WEBRTC_WIN)
  // Append separator character if needed.
  if (path_str.back() != '\\')
    path_str += '\\';

  // Init.
  WIN32_FIND_DATAW data;
  HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path_str + '*').c_str(), &data);
  if (handle == INVALID_HANDLE_VALUE)
    return absl::optional<std::vector<std::string>>();

  // Populate output.
  std::vector<std::string> found_entries;
  do {
    const std::string name = rtc::ToUtf8(data.cFileName);
    if (name != "." && name != "..")
      found_entries.emplace_back(path_str + name);
  } while (::FindNextFileW(handle, &data) == TRUE);

  // Release resources.
  if (handle != INVALID_HANDLE_VALUE)
    ::FindClose(handle);
#else
  // Append separator character if needed.
  if (path_str.back() != '/')
    path_str += '/';

  // Init.
  DIR* dir = ::opendir(path_str.c_str());
  if (dir == nullptr)
    return absl::optional<std::vector<std::string>>();

  // Populate output.
  std::vector<std::string> found_entries;
  while (dirent* dirent = readdir(dir)) {
    const std::string& name = dirent->d_name;
    if (name != "." && name != "..")
      found_entries.emplace_back(path_str + name);
  }

  // Release resources.
  closedir(dir);
#endif

  return absl::optional<std::vector<std::string>>(std::move(found_entries));
}

bool CreateDir(absl::string_view directory_name) {
  std::string directory_name_str(directory_name);
  struct stat path_info = {0};
  // Check if the path exists already:
  if (stat(directory_name_str.c_str(), &path_info) == 0) {
    if (!S_ISDIR(path_info.st_mode)) {
      fprintf(stderr,
              "Path %s exists but is not a directory! Remove this "
              "file and re-run to create the directory.\n",
              directory_name_str.c_str());
      return false;
    }
  } else {
#ifdef WIN32
    return _mkdir(directory_name_str.c_str()) == 0;
#else
    return mkdir(directory_name_str.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
#endif
  }
  return true;
}

bool RemoveDir(absl::string_view directory_name) {
#ifdef WIN32
  return RemoveDirectoryA(std::string(directory_name).c_str()) != FALSE;
#else
  return rmdir(std::string(directory_name).c_str()) == 0;
#endif
}

bool RemoveFile(absl::string_view file_name) {
#ifdef WIN32
  return DeleteFileA(std::string(file_name).c_str()) != FALSE;
#else
  return unlink(std::string(file_name).c_str()) == 0;
#endif
}

std::string ResourcePath(absl::string_view name, absl::string_view extension) {
  return webrtc::test::internal::ResourcePath(name, extension);
}

std::string JoinFilename(absl::string_view dir, absl::string_view name) {
  RTC_CHECK(!dir.empty()) << "Special cases not implemented.";
  rtc::StringBuilder os;
  os << dir;
  // If the directory path already ends with a path delimiter don't append it
  if (dir.back() != kPathDelimiter.back()) {
    os << kPathDelimiter;
  }
  os << name;
  return os.Release();
}

size_t GetFileSize(absl::string_view filename) {
  FILE* f = fopen(std::string(filename).c_str(), "rb");
  size_t size = 0;
  if (f != NULL) {
    if (fseek(f, 0, SEEK_END) == 0) {
      size = ftell(f);
    }
    fclose(f);
  }
  return size;
}

}  // namespace test
}  // namespace webrtc
