#include "persistent_json_storage.hpp"

#include <phosphor-logging/log.hpp>

#include <format>
#include <fstream>
#include <stdexcept>

using namespace std::literals::string_literals;

bool isAnySymlink(const std::filesystem::path& path)
{
    auto currentPath = path;
    while (currentPath != path.root_path())
    {
        if (std::filesystem::is_symlink(currentPath))
        {
            std::string warningStr = std::format("{} is a symlink",
                                                 currentPath.string());
            phosphor::logging::log<phosphor::logging::level::WARNING>(
                warningStr.c_str());
            return true;
        }
        currentPath = currentPath.parent_path();
    }
    return false;
}

PersistentJsonStorage::PersistentJsonStorage(const DirectoryPath& directory) :
    directory(directory)
{}

void PersistentJsonStorage::store(const FilePath& filePath,
                                  const nlohmann::json& data)
{
    try
    {
        const auto path = join(directory, filePath);
        std::error_code ec;

        phosphor::logging::log<phosphor::logging::level::DEBUG>(
            "Store to file", phosphor::logging::entry("PATH=%s", path.c_str()));

        std::filesystem::create_directories(path.parent_path(), ec);
        if (ec)
        {
            throw std::runtime_error(
                "Unable to create directory for file: " + path.string() +
                ", ec=" + std::to_string(ec.value()) + ": " + ec.message());
        }

        assertThatPathIsNotSymlink(path);

        std::ofstream file(path);
        file << data;
        if (!file)
        {
            throw std::runtime_error("Unable to create file: " + path.string());
        }

        limitPermissions(path.parent_path());
        limitPermissions(path);
    }
    catch (...)
    {
        remove(filePath);
        throw;
    }
}

bool PersistentJsonStorage::remove(const FilePath& filePath)
{
    const auto path = join(directory, filePath);

    if (isAnySymlink(path))
    {
        return false;
    }

    std::error_code ec;

    auto removed = std::filesystem::remove(path, ec);
    if (!removed)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Unable to remove file",
            phosphor::logging::entry("PATH=%s", path.c_str()),
            phosphor::logging::entry("ERROR_CODE=%d", ec.value()));
        return false;
    }

    /* removes directory only if it is empty */
    std::filesystem::remove(path.parent_path(), ec);

    return true;
}

std::optional<nlohmann::json>
    PersistentJsonStorage::load(const FilePath& filePath) const
{
    const auto path = join(directory, filePath);
    if (!std::filesystem::exists(path))
    {
        return std::nullopt;
    }

    nlohmann::json result;

    try
    {
        assertThatPathIsNotSymlink(path);
        std::ifstream file(path);
        file >> result;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
        return std::nullopt;
    }

    return result;
}

std::vector<interfaces::JsonStorage::FilePath>
    PersistentJsonStorage::list() const
{
    std::vector<interfaces::JsonStorage::FilePath> result;
    if (!std::filesystem::exists(directory))
    {
        return result;
    }

    for (const auto& p :
         std::filesystem::recursive_directory_iterator(directory))
    {
        if (p.is_regular_file() && !isAnySymlink(p.path()))
        {
            auto item = std::filesystem::relative(p.path(), directory);
            result.emplace_back(std::move(item));
        }
    }

    return result;
}

std::filesystem::path
    PersistentJsonStorage::join(const std::filesystem::path& left,
                                const std::filesystem::path& right)
{
    return left / right;
}

void PersistentJsonStorage::limitPermissions(const std::filesystem::path& path)
{
    constexpr auto filePerms = std::filesystem::perms::owner_read |
                               std::filesystem::perms::owner_write;
    constexpr auto dirPerms = filePerms | std::filesystem::perms::owner_exec;
    std::filesystem::permissions(
        path, std::filesystem::is_directory(path) ? dirPerms : filePerms,
        std::filesystem::perm_options::replace);
}

bool PersistentJsonStorage::exist(const FilePath& subPath) const
{
    return std::filesystem::exists(join(directory, subPath));
}

void PersistentJsonStorage::assertThatPathIsNotSymlink(
    const std::filesystem::path& path)
{
    if (isAnySymlink(path))
    {
        throw std::runtime_error(
            "Source/Target file is a symlink! Operation canceled on path "s +
            path.c_str());
    }
}
