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

#include <assert.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 <codecvt>
#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 "rtc_base/checks.h"
#include "rtc_base/string_utils.h"
#include "test/testsupport/file_utils_override.h"

namespace webrtc {
namespace test {

#if defined(WEBRTC_WIN)
const char* kPathDelimiter = "\\";
#else
const char* kPathDelimiter = "/";
#endif

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

  std::string result = path;
  if (result.back() == *kPathDelimiter)
    result.pop_back();  // Remove trailing separator.

  return result.substr(0, result.find_last_of(kPathDelimiter));
}

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

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

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

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(const std::string& dir, const std::string& 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);
  assert(false);
  return "";
#else
  int len = dir.size() + prefix.size() + 2 + 6;
  std::unique_ptr<char[]> tempname(new char[len]);

  snprintf(tempname.get(), len, "%s/%sXXXXXX", dir.c_str(), prefix.c_str());
  int fd = ::mkstemp(tempname.get());
  if (fd == -1) {
    assert(false);
    return "";
  } else {
    ::close(fd);
  }
  std::string ret(tempname.get());
  return ret;
#endif
}

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

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

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

  // Init.
  WIN32_FIND_DATAW data;
  HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path + '*').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 + name);
  } while (::FindNextFileW(handle, &data) == TRUE);

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

  // Init.
  DIR* dir = ::opendir(path.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 + name);
  }

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

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

bool CreateDir(const std::string& directory_name) {
  struct stat path_info = {0};
  // Check if the path exists already:
  if (stat(directory_name.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.c_str());
      return false;
    }
  } else {
#ifdef WIN32
    return _mkdir(directory_name.c_str()) == 0;
#else
    return mkdir(directory_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
#endif
  }
  return true;
}

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

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

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

std::string JoinFilename(const std::string& dir, const std::string& name) {
  RTC_CHECK(!dir.empty()) << "Special cases not implemented.";
  return dir + kPathDelimiter + name;
}

size_t GetFileSize(const std::string& filename) {
  FILE* f = fopen(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
