#include <libpdbg.h>

#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>

#include <iomanip>

using namespace phosphor::logging;

namespace attn
{

/**
 * @brief Handle SBE vital attention
 *
 * @return 0 = success
 */
int handleVital();

/**
 * @brief Handle checkstop attention
 *
 * @return 0 = success
 */
int handleCheckstop();

/**
 * @brief Handle special attention
 *
 * @param i_breakpoints true = breakpoint special attn handling enabled
 * @return 0 = success
 */
int handleSpecial(bool i_breakpoints);

/**
 * @brief Notify Cronus over dbus interface
 *
 * @param i_proc   Processor number with Special attention
 * @param i_core   Core number with special attention
 * @param i_thread Thread number with special attention
 */
void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread);

/**
 * @brief Start host diagnostic mode
 *
 * Start the host diagnostic mode systemd unit
 */
void startHostDiagnosticMode();

/**
 * @brief The main attention handler logic
 *
 * @param i_breakpoints true = breakpoint special attn handling enabled
 */
void attnHandler(bool i_breakpoints)
{
    uint32_t isr_val, isr_mask;
    uint32_t proc;

    // loop through processors looking for active attentions
    pdbg_target* target;
    pdbg_for_each_class_target("fsi", target)
    {
        if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
        {
            proc = pdbg_target_index(target); // get processor number

            std::stringstream ss; // log message stream
            ss << "[ATTN] checking processor " << proc << std::endl;
            log<level::INFO>(ss.str().c_str());

            // get active attentions on processor
            if (0 != fsi_read(target, 0x1007, &isr_val))
            {
                std::stringstream ss; // log message stream
                ss << "[ATTN] Error! cfam read 0x1007 FAILED" << std::endl;
                log<level::INFO>(ss.str().c_str());
            }
            else
            {
                std::stringstream ss; // log message stream
                ss << "[ATTN] cfam 0x1007 = 0x";
                ss << std::hex << std::setw(8) << std::setfill('0');
                ss << isr_val << std::endl;
                log<level::INFO>(ss.str().c_str());

                // get interrupt enabled special attentions mask
                if (0 != fsi_read(target, 0x100d, &isr_mask))
                {
                    std::stringstream ss; // log message stream
                    ss << "[ATTN] Error! cfam read 0x100d FAILED" << std::endl;
                    log<level::INFO>(ss.str().c_str());
                }
                else
                {
                    std::stringstream ss; // log message stream
                    ss << "[ATTN] cfam 0x100d = 0x";
                    ss << std::hex << std::setw(8) << std::setfill('0');
                    ss << isr_mask << std::endl;
                    log<level::INFO>(ss.str().c_str());

                    // bit 0 on "left": bit 30 = SBE vital attention
                    if (isr_val & isr_mask & 0x00000002)
                    {
                        handleVital();
                    }

                    // bit 0 on "left": bit 1 = checkstop
                    if (isr_val & isr_mask & 0x40000000)
                    {
                        handleCheckstop();
                    }

                    // bit 0 on "left": bit 2 = special attention
                    if (isr_val & isr_mask & 0x20000000)
                    {
                        handleSpecial(i_breakpoints);
                    }
                } // cfam 0x100d valid
            }     // cfam 0x1007 valid
        }         // fsi target enabled
    }             // next processor

    return; // checked all processors
}

/**
 * @brief Handle SBE vital attention
 */
int handleVital()
{
    int rc = 1; // vital attention handling not yet supported

    std::stringstream ss; // log message stream
    ss << "[ATTN] vital" << std::endl;
    log<level::INFO>(ss.str().c_str());

    if (0 != rc)
    {
        std::stringstream ss; // log message stream
        ss << "[ATTN] vital NOT handled" << std::endl;
        log<level::INFO>(ss.str().c_str());
    }

    return rc;
}

/**
 * @brief Handle checkstop attention
 */
int handleCheckstop()
{
    int rc = 1; // checkstop handling not yet supported

    std::stringstream ss; // log message stream
    ss << "[ATTN] checkstop" << std::endl;
    log<level::INFO>(ss.str().c_str());

    if (0 != rc)
    {
        std::stringstream ss; // log message stream
        ss << "[ATTN] checkstop NOT handled" << std::endl;
        log<level::INFO>(ss.str().c_str());
    }

    // TODO recoverable errors?

    return rc;
}

/**
 * @brief Handle special attention
 *
 * @param i_breakpoints true = breakpoint special attn handling enabled
 */
int handleSpecial(bool i_breakpoints)
{
    int rc = 0; // special attention handling supported

    std::stringstream ss; // log message stream

    ss << "[ATTN] special" << std::endl;

    // Right now we always handle breakpoint special attentions if breakpoint
    // attn handling is enabled. This will eventually check if breakpoint attn
    // handing is enabled AND there is a breakpoint pending.
    if (true == i_breakpoints)
    {
        ss << "[ATTN] breakpoint" << std::endl;
        log<level::INFO>(ss.str().c_str());

        // Cronus will determine proc, core and thread so just notify
        notifyCronus(0, 0, 0); // proc-0, core-0, thread-0
    }
    // Right now if breakpoint attn handling is not enabled we will treat the
    // special attention as a TI. This will eventually be changed to check
    // whether a TI is active and handle it regardless of whether breakpoint
    // handling is enbaled or not.
    else
    {
        ss << "[ATTN] TI (terminate immediately)" << std::endl;
        log<level::INFO>(ss.str().c_str());

        // Start host diagnostic mode
        startHostDiagnosticMode();
    }

    // TODO recoverable errors?

    return rc;
}

/**
 * @brief Notify Cronus over dbus interface
 */
void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread)
{
    std::stringstream ss; // log message stream

    // log status info
    ss << "[ATTN] notify ";
    ss << i_proc << ", " << i_core << ", " << i_thread << std::endl;
    log<level::INFO>(ss.str().c_str());

    // notify Cronus over dbus
    auto bus = sdbusplus::bus::new_system();
    auto msg = bus.new_signal("/", "org.openbmc.cronus", "Brkpt");

    std::array<uint32_t, 3> params{i_proc, i_core, i_thread};
    msg.append(params);

    msg.signal_send();

    return;
}

/**
 * @brief Start host diagnostic mode
 * */
void startHostDiagnosticMode()
{
    std::stringstream ss; // log message stream

    // log status info
    ss << "[ATTN] start host diagnostic mode service" << std::endl;
    log<level::INFO>(ss.str().c_str());

    // Use the systemd service manager object interface to call the start unit
    // method with the obmc-host-diagnostic-mode target.
    auto bus    = sdbusplus::bus::new_system();
    auto method = bus.new_method_call(
        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
        "org.freedesktop.systemd1.Manager", "StartUnit");

    method.append("obmc-host-diagnostic-mode@0.target"); // unit to activate
    method.append("replace"); // mode = replace conflicting queued jobs
    bus.call_noreply(method); // start the service

    return;
}

} // namespace attn
