/*
 *  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);
    if (std::filesystem::create_directory(path)) {
        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)) {
        std::string fname {entry.path().filename().string()};
        if (fname == "." || fname == "..")
            continue;
        files.emplace_back(std::move(fname));
    }
    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, true);

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

    return std::remove(path.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)) {
        for (const auto& entry: std::filesystem::directory_iterator(path)) {
            auto fname = entry.path().filename().string();
            if (fname == "." || fname == "..")
                continue;
            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), 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), 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), 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), 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).c_str(), mode);
#else
    return access(file.c_str(), mode);
#endif
}

} // namespace fileutils
} // namespace dhtnet
