#include <attn/attention.hpp>
#include <attn/attn_common.hpp>
#include <attn/attn_dump.hpp>
#include <attn/attn_handler.hpp>
#include <attn/attn_logging.hpp>
#include <sdbusplus/bus.hpp>
#include <util/dbus.hpp>
#include <util/pdbg.hpp>
#include <util/pldm.hpp>
#include <util/trace.hpp>

namespace attn
{
/*
 * @brief Request SBE hreset and try to clear sbe attentions
 *
 * @param[in] sbeInstance - sbe instance to hreset (0 based)
 *
 * @return true if hreset is successful and attentions cleared
 */
bool attemptSbeRecovery(int sbeInstance)
{
    // attempt sbe hreset and attention interrupt clear
    if (!util::pldm::hresetSbe(sbeInstance))
    {
        return false;
    }

    trace::inf("hreset completed");

    // try to clear attention interrupts
    clearAttnInterrupts();

    // loop through processors checking attention interrupts
    bool recovered = true;
    pdbg_target* procTarget;
    pdbg_for_each_class_target("proc", procTarget)
    {
        // active processors only
        if (PDBG_TARGET_ENABLED !=
            pdbg_target_probe(util::pdbg::getPibTrgt(procTarget)))
        {
            continue;
        }

        // get cfam is an fsi read
        pdbg_target* fsiTarget = util::pdbg::getFsiTrgt(procTarget);
        uint32_t int_val;

        // get attention interrupts on processor
        if (RC_SUCCESS == fsi_read(fsiTarget, 0x100b, &int_val))
        {
            if (int_val & SBE_ATTN)
            {
                trace::err("sbe attention did not clear");
                recovered = false;
                break;
            }
        }
        else
        {
            // log cfam read error
            trace::err("cfam read error");
            recovered = false;
            break;
        }
    }

    if (recovered)
    {
        trace::inf("sbe attention cleared");
    }

    return recovered;
}

/**
 * @brief Check for active checkstop attention
 *
 * @param procInstance - proc to check for attentions
 *
 * @pre pdbg target associated with proc instance is enabled for fsi access
 *
 * @return true if checkstop acive false otherwise
 * */
bool checkstopActive(int procInstance)
{
    // get fsi target
    char path[16];
    sprintf(path, "/proc%d/fsi", procInstance);
    pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
    if (nullptr == fsiTarget)
    {
        trace::inf("fsi path or target not found");
        return false;
    }

    // check for active checkstop attention
    int r;
    uint32_t isr_val, isr_mask;

    isr_val = 0xffffffff;
    r = fsi_read(fsiTarget, 0x1007, &isr_val);
    if ((RC_SUCCESS != r) || (0xffffffff == isr_val))
    {
        trace::err("cfam 1007 read error");
        return false;
    }

    isr_mask = 0xffffffff;
    r = fsi_read(fsiTarget, 0x100d, &isr_mask);
    if ((RC_SUCCESS != r) || (0xffffffff == isr_mask))
    {
        trace::err("cfam 100d read error");
        return false;
    }

    return activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN);
}

/**
 * @brief Handle SBE vital attention
 *
 * @param i_attention - attention object
 *
 * @return non-zero if attention was not successfully handled
 */
int handleVital(Attention* i_attention)
{
    trace::inf("vital handler started");

    // if vital handling disabled
    if (false == (i_attention->getConfig()->getFlag(enVital)))
    {
        trace::inf("vital handling disabled");
        return RC_NOT_HANDLED;
    }

    // if power fault then we don't do anything
    sleepSeconds(POWER_FAULT_WAIT);
    if (util::dbus::powerFault())
    {
        trace::inf("power fault was reported");
        return RC_SUCCESS;
    }

    // if no checkstop and host is running
    int instance =
        pdbg_target_index(i_attention->getTarget()); // get processor number

    if (!checkstopActive(instance) &&
        util::dbus::HostRunningState::Started == util::dbus::hostRunningState())
    {
        // attempt to recover the sbe
        if (attemptSbeRecovery(instance))
        {
            eventVital(levelPelInfo);
            return RC_SUCCESS;
        }
    }

    // host not running, checkstop active or recovery failed
    auto pelId = eventVital(levelPelError);
    requestDump(pelId, DumpParameters{0, DumpType::SBE});
    util::dbus::transitionHost(util::dbus::HostState::Quiesce);

    return RC_SUCCESS;
}

} // namespace attn
