/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "fileutils.h"

#include <opendht/crypto.h>

#ifdef RING_UWP
#include <io.h> // for access and close
#endif

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

#ifdef _WIN32
#include <windows.h>
#include "string_utils.h"
#endif

#include <sys/types.h>
#include <sys/stat.h>
#ifndef _MSC_VER
#include <libgen.h>
#endif
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>

#include <sstream>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <limits>
#include <array>
#include <filesystem>

#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cstddef>
#include <ciso646>


#define ERASE_BLOCK 4096

namespace dhtnet {
namespace fileutils {

// returns true if directory exists or was created
bool
check_dir(const std::filesystem::path& path, mode_t dirmode, mode_t parentmode)
{
    if (std::filesystem::exists(path))
        return true;
    if (path.has_parent_path())
        check_dir(path.parent_path(), parentmode, parentmode);
    std::error_code ec;
    if (std::filesystem::create_directory(path, ec)) {
        std::filesystem::permissions(path, (std::filesystem::perms)dirmode);
        return true;
    }
    return false;
}

std::mutex&
getFileLock(const std::filesystem::path& path)
{
    static std::mutex fileLockLock {};
    static std::map<std::string, std::mutex> fileLocks {};

    std::lock_guard<std::mutex> l(fileLockLock);
    return fileLocks[path.string()];
}

bool
isFile(const std::filesystem::path& path, bool resolveSymlink)
{
    auto status = resolveSymlink ? std::filesystem::status(path) : std::filesystem::symlink_status(path);
    return std::filesystem::is_regular_file(status);
}

bool
isDirectory(const std::filesystem::path& path)
{
    return std::filesystem::is_directory(path);
}

bool
hasHardLink(const std::filesystem::path& path)
{
    return std::filesystem::hard_link_count(path) > 1;
}

bool
isSymLink(const std::filesystem::path& path)
{
    return std::filesystem::is_symlink(path);
}

template <typename TP>
std::chrono::system_clock::time_point to_sysclock(TP tp)
{
    using namespace std::chrono;
    return time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
}

bool
createSymlink(const std::string& linkFile, const std::string& target)
{
    try {
        std::filesystem::create_symlink(target, linkFile);
    } catch (const std::exception& e) {
        //JAMI_ERR("Couldn't create soft link: %s", e.what());
        return false;
    }
    return true;
}

bool
createHardlink(const std::string& linkFile, const std::string& target)
{
    try {
        std::filesystem::create_hard_link(target, linkFile);
    } catch (const std::exception& e) {
        //JAMI_ERR("Couldn't create hard link: %s", e.what());
        return false;
    }
    return true;
}

void
createFileLink(const std::string& linkFile, const std::string& target, bool hard)
{
    if (not hard or not createHardlink(linkFile, target))
        createSymlink(linkFile, target);
}

std::vector<uint8_t>
loadFile(const std::filesystem::path& path)
{
    std::vector<uint8_t> buffer;
    std::ifstream file = ifstream(path, std::ios::binary);
    if (!file)
        throw std::runtime_error("Can't read file: " + path.string());
    file.seekg(0, std::ios::end);
    auto size = file.tellg();
    if (size > std::numeric_limits<unsigned>::max())
        throw std::runtime_error("File is too big: " + path.string());
    buffer.resize(size);
    file.seekg(0, std::ios::beg);
    if (!file.read((char*) buffer.data(), size))
        throw std::runtime_error("Can't load file: " + path.string());
    return buffer;
}

void
saveFile(const std::filesystem::path& path, const uint8_t* data, size_t data_size, mode_t mode)
{
    std::ofstream file = fileutils::ofstream(path, std::ios::trunc | std::ios::binary);
    if (!file.is_open()) {
        //JAMI_ERR("Could not write data to %s", path.c_str());
        return;
    }
    file.write((char*) data, data_size);
    file.close();
    std::filesystem::permissions(path, (std::filesystem::perms)mode);
}

std::vector<std::string>
readDirectory(const std::filesystem::path& dir)
{
    std::vector<std::string> files;
    std::error_code ec;
    for (const auto& entry : std::filesystem::directory_iterator(dir, ec)) {
        files.emplace_back(entry.path().filename().string());
    }
    return files;
}

bool
recursive_mkdir(const std::filesystem::path& path, mode_t mode)
{
    std::error_code ec;
    std::filesystem::create_directories(path, ec);
    if (!ec)
        std::filesystem::permissions(path, (std::filesystem::perms)mode, ec);
    return !ec;
}

#ifdef _WIN32
bool
eraseFile_win32(const std::string& path, bool dosync)
{
    HANDLE h
        = CreateFileA(path.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE) {
        // JAMI_WARN("Can not open file %s for erasing.", path.c_str());
        return false;
    }

    LARGE_INTEGER size;
    if (!GetFileSizeEx(h, &size)) {
        // JAMI_WARN("Can not erase file %s: GetFileSizeEx() failed.", path.c_str());
        CloseHandle(h);
        return false;
    }
    if (size.QuadPart == 0) {
        CloseHandle(h);
        return false;
    }

    uint64_t size_blocks = size.QuadPart / ERASE_BLOCK;
    if (size.QuadPart % ERASE_BLOCK)
        size_blocks++;

    char* buffer;
    try {
        buffer = new char[ERASE_BLOCK];
    } catch (std::bad_alloc& ba) {
        // JAMI_WARN("Can not allocate buffer for erasing %s.", path.c_str());
        CloseHandle(h);
        return false;
    }
    memset(buffer, 0x00, ERASE_BLOCK);

    OVERLAPPED ovlp;
    if (size.QuadPart < (1024 - 42)) { // a small file can be stored in the MFT record
        ovlp.Offset = 0;
        ovlp.OffsetHigh = 0;
        WriteFile(h, buffer, (DWORD) size.QuadPart, 0, &ovlp);
        FlushFileBuffers(h);
    }
    for (uint64_t i = 0; i < size_blocks; i++) {
        uint64_t offset = i * ERASE_BLOCK;
        ovlp.Offset = offset & 0x00000000FFFFFFFF;
        ovlp.OffsetHigh = offset >> 32;
        WriteFile(h, buffer, ERASE_BLOCK, 0, &ovlp);
    }

    delete[] buffer;

    if (dosync)
        FlushFileBuffers(h);

    CloseHandle(h);
    return true;
}

#else

bool
eraseFile_posix(const std::string& path, bool dosync)
{
    struct stat st;
    if (stat(path.c_str(), &st) == -1) {
        //JAMI_WARN("Can not erase file %s: fstat() failed.", path.c_str());
        return false;
    }
    // Remove read-only flag if possible
    chmod(path.c_str(), st.st_mode | (S_IWGRP+S_IWUSR) );

    int fd = open(path.c_str(), O_WRONLY);
    if (fd == -1) {
        //JAMI_WARN("Can not open file %s for erasing.", path.c_str());
        return false;
    }

    if (st.st_size == 0) {
        close(fd);
        return false;
    }

    lseek(fd, 0, SEEK_SET);

    std::array<char, ERASE_BLOCK> buffer;
    buffer.fill(0);
    decltype(st.st_size) written(0);
    while (written < st.st_size) {
        auto ret = write(fd, buffer.data(), buffer.size());
        if (ret < 0) {
            //JAMI_WARNING("Error while overriding file with zeros.");
            break;
        } else
            written += ret;
    }

    if (dosync)
        fsync(fd);

    close(fd);
    return written >= st.st_size;
}
#endif

bool
eraseFile(const std::string& path, bool dosync)
{
#ifdef _WIN32
    return eraseFile_win32(path, dosync);
#else
    return eraseFile_posix(path, dosync);
#endif
}

int
remove(const std::filesystem::path& path, bool erase)
{
    if (erase and isFile(path, false) and !hasHardLink(path))
        eraseFile(path.string(), true);

#ifdef _WIN32
    // use Win32 api since std::remove will not unlink directory in use
    if (isDirectory(path))
        return !RemoveDirectory(dhtnet::to_wstring(path.string()).c_str());
#endif

    return std::remove(path.string().c_str());
}

int
removeAll(const std::filesystem::path& path, bool erase)
{
    if (path.empty())
        return -1;

    auto status = std::filesystem::status(path);
    if (std::filesystem::is_directory(status) and not std::filesystem::is_symlink(status)) {
        std::error_code ec;
        for (const auto& entry: std::filesystem::directory_iterator(path, ec)) {
            removeAll(entry.path(), erase);
        }
    }
    return remove(path, erase);
}

void
openStream(std::ifstream& file, const std::filesystem::path& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    file.open(dhtnet::to_wstring(path.string()), mode);
#else
    file.open(path, mode);
#endif
}

void
openStream(std::ofstream& file, const std::filesystem::path& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    file.open(dhtnet::to_wstring(path.string()), mode);
#else
    file.open(path, mode);
#endif
}

std::ifstream
ifstream(const std::filesystem::path& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    return std::ifstream(dhtnet::to_wstring(path.string()), mode);
#else
    return std::ifstream(path, mode);
#endif
}

std::ofstream
ofstream(const std::filesystem::path& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    return std::ofstream(dhtnet::to_wstring(path.string()), mode);
#else
    return std::ofstream(path, mode);
#endif
}

int
accessFile(const std::filesystem::path& file, int mode)
{
#ifdef _WIN32
    return _waccess(dhtnet::to_wstring(file.string()).c_str(), mode);
#else
    return access(file.c_str(), mode);
#endif
}

} // namespace fileutils
} // namespace dhtnet
