#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());
    }
}
