#include <assert.h>
#include <unistd.h>

#include <analyzer/analyzer_main.hpp>
#include <analyzer/ras-data/ras-data-parser.hpp>
#include <analyzer/service_data.hpp>
#include <attn/attn_dump.hpp>
#include <hei_main.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>

namespace analyzer
{
//------------------------------------------------------------------------------

// Forward references for externally defined functions.

/**
 * @brief Will get the list of active chip and initialize the isolator.
 * @param o_chips The returned list of active chips.
 */
void initializeIsolator(std::vector<libhei::Chip>& o_chips);

/**
 * @brief  Will get the list of active chip and initialize the isolator.
 * @param  i_type      The type of analysis to perform. See enum for details.
 * @param  i_isoData   The data gathered during isolation (for FFDC).
 * @param  o_rootCause The returned root cause signature.
 * @param  i_rasData   The RAS data parser.
 * @return True, if root cause has been found. False, otherwise.
 */
bool filterRootCause(AnalysisType i_type,
                     const libhei::IsolationData& i_isoData,
                     libhei::Signature& o_rootCause,
                     const RasDataParser& i_rasData);

/**
 * @brief Will create and submit a PEL using the given data.
 * @param i_servData  Data regarding service actions gathered during analysis.
 * @return The platform log ID. Will return zero if no PEL is generated.
 */
uint32_t commitPel(const ServiceData& i_servData);

//------------------------------------------------------------------------------

const char* __attn(libhei::AttentionType_t i_type)
{
    const char* str = "";
    switch (i_type)
    {
        case libhei::ATTN_TYPE_CHECKSTOP:
            str = "CHECKSTOP";
            break;
        case libhei::ATTN_TYPE_UNIT_CS:
            str = "UNIT_CS";
            break;
        case libhei::ATTN_TYPE_RECOVERABLE:
            str = "RECOVERABLE";
            break;
        case libhei::ATTN_TYPE_SP_ATTN:
            str = "SP_ATTN";
            break;
        case libhei::ATTN_TYPE_HOST_ATTN:
            str = "HOST_ATTN";
            break;
        default:
            trace::err("Unsupported attention type: %u", i_type);
            assert(0);
    }
    return str;
}

//------------------------------------------------------------------------------

const char* __analysisType(AnalysisType i_type)
{
    const char* str = "";
    switch (i_type)
    {
        case AnalysisType::SYSTEM_CHECKSTOP:
            str = "SYSTEM_CHECKSTOP";
            break;
        case AnalysisType::TERMINATE_IMMEDIATE:
            str = "TERMINATE_IMMEDIATE";
            break;
        case AnalysisType::MANUAL:
            str = "MANUAL";
            break;
        default:
            trace::err("Unsupported analysis type: %u", i_type);
            assert(0);
    }
    return str;
}

//------------------------------------------------------------------------------

uint32_t analyzeHardware(AnalysisType i_type, attn::DumpParameters& o_dump)
{
    uint32_t o_plid = 0; // default, zero indicates PEL was not created

    if (!util::pdbg::queryHardwareAnalysisSupported())
    {
        trace::err("Hardware error analysis is not supported on this system");
        return o_plid;
    }

    trace::inf(">>> enter analyzeHardware(%s)", __analysisType(i_type));

    // Initialize the isolator and get all of the chips to be analyzed.
    trace::inf("Initializing the isolator...");
    std::vector<libhei::Chip> chips;
    initializeIsolator(chips);

    // Isolate attentions.
    trace::inf("Isolating errors: # of chips=%u", chips.size());
    libhei::IsolationData isoData{};
    libhei::isolate(chips, isoData);

    // For debug, trace out the original list of signatures before filtering.
    for (const auto& sig : isoData.getSignatureList())
    {
        trace::inf("Signature: %s 0x%0" PRIx32 " %s",
                   util::pdbg::getPath(sig.getChip()), sig.toUint32(),
                   __attn(sig.getAttnType()));
    }

    // Filter for root cause attention.
    libhei::Signature rootCause{};
    RasDataParser rasData{};
    bool attnFound = false;
    try
    {
        attnFound = filterRootCause(i_type, isoData, rootCause, rasData);
    }
    catch (const std::exception& e)
    {
        trace::err("Exception caught during root cause filtering");
        trace::err(e.what());
        attnFound = false; // just in case
    }

    // If a root cause attention was found, or if this was a system checkstop,
    // generate a PEL.
    if (attnFound || AnalysisType::SYSTEM_CHECKSTOP == i_type)
    {
        if (attnFound)
        {
            trace::inf("Root cause attention: %s 0x%0" PRIx32 " %s",
                       util::pdbg::getPath(rootCause.getChip()),
                       rootCause.toUint32(), __attn(rootCause.getAttnType()));
        }
        else
        {
            // This is bad. Analysis should have found a root cause attention
            // for a system checkstop. Issues could range from code bugs to SCOM
            // errors. Regardless, generate a PEL with FFDC to assist with
            // debug.
            trace::err("System checkstop with no root cause attention");
            rootCause = libhei::Signature{}; // just in case
        }

        // Start building the service data.
        ServiceData servData{rootCause, i_type, isoData};

        // Apply any service actions, if needed. Note that there are no
        // resolutions for manual analysis.
        if (AnalysisType::MANUAL != i_type)
        {
            if (attnFound)
            {
                try
                {
                    // Resolve the root cause attention.
                    rasData.getResolution(rootCause)->resolve(servData);
                }
                catch (const std::exception& e)
                {
                    trace::err("Exception caught during root cause analysis");
                    trace::err(e.what());

                    // We'll still want to create a PEL for the FFDC, but
                    // since the analysis failed, we need to callout Level 2
                    // Support.
                    servData.calloutProcedure(callout::Procedure::NEXTLVL,
                                              callout::Priority::HIGH);
                }
            }
            else
            {
                // Analysis failed so callout the Level 2 Support.
                servData.calloutProcedure(callout::Procedure::NEXTLVL,
                                          callout::Priority::HIGH);
            }
        }

        // Create and commit a PEL.
        o_plid = commitPel(servData);

        if (0 == o_plid)
        {
            trace::err("Failed to create PEL");
        }
        else
        {
            trace::inf("PEL created: PLID=0x%0" PRIx32, o_plid);

            // Gather/return information needed for dump. A hardware dump will
            // always be used for system checkstop attenions. Software dumps
            // will be reserved for MP-IPLs during TI analysis.
            // TODO: Need ID from root cause. At the moment, HUID does not exist
            //       in devtree. Will need a better ID definition.
            o_dump.unitId   = 0;
            o_dump.dumpType = attn::DumpType::Hardware;
        }
    }
    else
    {
        // It is possible for TI handling, or manually initiated analysis via
        // the command line, that there will not be an active attention. In
        // which case, we will do nothing and let the caller of this function
        // determine if this is the expected behavior.
        trace::inf("No active attentions found");
    }

    // All done, clean up the isolator.
    trace::inf("Uninitializing isolator...");
    libhei::uninitialize();

    trace::inf("<<< exit analyzeHardware()");

    return o_plid;
}

//------------------------------------------------------------------------------

} // namespace analyzer
