#include "config.h"

#include "fw_update_watch.hpp"

#include "common_utils.hpp"
#include "create_pel.hpp"
#include "pdbg_utils.hpp"

#include <fmt/format.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <sdbusplus/exception.hpp>

#include <filesystem>

namespace openpower
{
namespace phal
{
namespace fwupdate
{
using namespace phosphor::logging;
namespace fs = std::filesystem;

using Message = std::string;
using Attributes = std::variant<Message>;
using PropertyName = std::string;
using PropertyMap = std::map<PropertyName, Attributes>;
using InterfaceName = std::string;
using InterfaceMap = std::map<InterfaceName, PropertyMap>;

void Watch::fwIntfAddedCallback(sdbusplus::message::message& msg)
{
    //  DBusInterfaceAdded interfaces;
    sdbusplus::message::object_path objectPath;
    InterfaceMap interfaceMap;

    try
    {
        msg.read(objectPath, interfaceMap);
    }
    catch (const sdbusplus::exception::exception& e)
    {
        log<level::ERR>(fmt::format("Failed to parse software add signal"
                                    "Exception [{}] REPLY_SIG [{}]",
                                    e.what(), msg.get_signature())
                            .c_str());
        return;
    }

    auto iter = interfaceMap.find("xyz.openbmc_project.Software.Activation");
    if (iter == interfaceMap.end())
    {
        // Skip not related Software Activation
        return;
    }

    auto attr = iter->second.find("Activation");
    if (attr == iter->second.end())
    {
        // Skip not related to Activation property.
        return;
    }

    auto& imageProperty = std::get<InterfaceName>(attr->second);
    if (imageProperty.empty())
    {
        // Skip, no image property
        return;
    }

    if (imageProperty ==
            "xyz.openbmc_project.Software.Activation.Activations.Ready" &&
        !isSoftwareUpdateInProgress())
    {
        log<level::INFO>("Software path interface add signal received");

        // Set status to code update in progress.
        // Interface added signal triggered multiple times in code update path,
        // it's due to additional interfaces added by the software manager app
        // after the version interface is created.
        // Device tree data collection is required only for the first trigger
        setSoftwareUpdateProgress(true);

        try
        {
            // Colect device tree data
            openpower::phal::fwupdate::exportDevtree();
        }
        catch (fs::filesystem_error& e)
        {
            log<level::ERR>(
                fmt::format("Filesystem error reported Error:({})", e.what())
                    .c_str());
            throw std::runtime_error(e.what());
        }

        log<level::INFO>("Successfully exported devtree attribute data");
    }

    return;
}

void exportDevtree()
{
    constexpr auto ERROR_DEVTREE_BACKUP =
        "org.open_power.PHAL.Error.devtreeBackup";

    // Check devtree export filter file is present
    auto path = fs::path(DEVTREE_EXPORT_FILTER_FILE);
    if (!fs::exists(path))
    {
        log<level::ERR>(
            fmt::format("devtree export filter file is not available: ({})",
                        DEVTREE_EXPORT_FILTER_FILE)
                .c_str());
        openpower::pel::createPEL(ERROR_DEVTREE_BACKUP);
        return;
    }

    // delete export data file if present
    auto expFile = fs::path(DEVTREE_EXP_FILE);
    if (fs::exists(expFile))
    {
        fs::remove_all(expFile);
    }
    else
    {
        // create directory
        fs::create_directory(expFile.parent_path());
    }

    // Update PDBG_DTB value
    openpower::phal::setDevtreeEnv();

    // Update PDATA_INFODB value
    openpower::phal::setPdataInfoDBEnv();

    int status = 0;
    pid_t pid = fork();
    if (pid == 0)
    {
        std::string cmd("/usr/bin/attributes ");
        cmd += "export ";
        cmd += DEVTREE_EXPORT_FILTER_FILE;
        cmd += " > ";
        cmd += DEVTREE_EXP_FILE;
        execl("/bin/sh", "sh", "-c", cmd.c_str(), 0);

        auto error = errno;
        log<level::ERR>(fmt::format("Error occurred during attributes function "
                                    "execution, errno({})",
                                    error)
                            .c_str());
        // Creating PEL at one place.
    }
    else if (pid > 0)
    {
        waitpid(pid, &status, 0);
        if (WEXITSTATUS(status))
        {
            log<level::ERR>("Failed to collect attribute export data");
            openpower::pel::createPEL(ERROR_DEVTREE_BACKUP);
        }
    }
    else
    {
        log<level::ERR>("exportDevtree fork() failed");
        std::runtime_error("exportDevtree fork() failed");
    }
}

} // namespace fwupdate
} // namespace phal
} // namespace openpower
