#include "config.h"

#include "serialize.hpp"

#include <cereal/archives/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/server.hpp>

#include <filesystem>
#include <fstream>
#include <system_error>

namespace phosphor
{
namespace software
{
namespace updater
{

PHOSPHOR_LOG2_USING;
namespace fs = std::filesystem;

const std::string priorityName = "priority";
const std::string purposeName = "purpose";

void storePriority(const std::string& flashId, uint8_t priority)
{
    std::error_code ec;
    auto path = fs::path(PERSIST_DIR) / flashId;
    if (!fs::is_directory(path, ec))
    {
        if (fs::exists(path, ec))
        {
            // Delete if it's a non-directory file
            warning("Removing non-directory file: {PATH}", "PATH", path);
            fs::remove_all(path, ec);
        }
        fs::create_directories(path, ec);
    }
    path = path / priorityName;

    std::ofstream os(path.c_str());
    cereal::JSONOutputArchive oarchive(os);
    oarchive(cereal::make_nvp(priorityName, priority));
}

void storePurpose(const std::string& flashId, VersionPurpose purpose)
{
    std::error_code ec;
    auto path = fs::path(PERSIST_DIR) / flashId;
    if (!fs::is_directory(path, ec))
    {
        if (fs::exists(path, ec))
        {
            // Delete if it's a non-directory file
            warning("Removing non-directory file: {PATH}", "PATH", path);
            fs::remove_all(path, ec);
        }
        fs::create_directories(path, ec);
    }
    path = path / purposeName;

    std::ofstream os(path.c_str());
    cereal::JSONOutputArchive oarchive(os);
    oarchive(cereal::make_nvp(purposeName, purpose));
}

bool restorePriority(const std::string& flashId, uint8_t& priority)
{
    std::error_code ec;
    auto path = fs::path(PERSIST_DIR) / flashId / priorityName;
    if (fs::exists(path, ec))
    {
        std::ifstream is(path.c_str(), std::ios::in);
        try
        {
            cereal::JSONInputArchive iarchive(is);
            iarchive(cereal::make_nvp(priorityName, priority));
            return true;
        }
        catch (const cereal::Exception& e)
        {
            fs::remove_all(path, ec);
        }
    }

    // Find the mtd device "u-boot-env" to retrieve the environment variables
    std::ifstream mtdDevices("/proc/mtd");
    std::string device, devicePath;

    try
    {
        while (std::getline(mtdDevices, device))
        {
            if (device.find("u-boot-env") != std::string::npos)
            {
                devicePath = "/dev/" + device.substr(0, device.find(':'));
                break;
            }
        }

        if (!devicePath.empty())
        {
            std::ifstream input(devicePath.c_str());
            std::string envVars;
            std::getline(input, envVars);

            std::string versionVar = flashId + "=";
            auto varPosition = envVars.find(versionVar);

            if (varPosition != std::string::npos)
            {
                // Grab the environment variable for this flashId. These
                // variables follow the format "flashId=priority\0"
                auto var = envVars.substr(varPosition);
                priority = std::stoi(var.substr(versionVar.length()));
                return true;
            }
        }
    }
    catch (const std::exception& e)
    {
        error("Error during processing: {ERROR}", "ERROR", e);
    }

    return false;
}

bool restorePurpose(const std::string& flashId, VersionPurpose& purpose)
{
    std::error_code ec;
    auto path = fs::path(PERSIST_DIR) / flashId / purposeName;
    if (fs::exists(path, ec))
    {
        std::ifstream is(path.c_str(), std::ios::in);
        try
        {
            cereal::JSONInputArchive iarchive(is);
            iarchive(cereal::make_nvp(purposeName, purpose));
            return true;
        }
        catch (const cereal::Exception& e)
        {
            fs::remove_all(path, ec);
        }
    }

    return false;
}

void removePersistDataDirectory(const std::string& flashId)
{
    std::error_code ec;
    auto path = fs::path(PERSIST_DIR) / flashId;
    if (fs::exists(path, ec))
    {
        fs::remove_all(path, ec);
    }
}

} // namespace updater
} // namespace software
} // namespace phosphor
