#include <stdio.h>

#include <analyzer/analyzer_main.hpp>
#include <analyzer/resolution.hpp>
#include <util/trace.hpp>

#include <regex>

#include "gtest/gtest.h"

// Chip string
constexpr auto chip_str = "/proc0";

// Unit paths
constexpr auto proc_str   = "";
constexpr auto iolink_str = "pib/perv24/pauc0/iohs0/smpgroup0";
constexpr auto omi_str    = "pib/perv12/mc0/mi0/mcc0/omi0";
constexpr auto ocmb_str   = "pib/perv12/mc0/mi0/mcc0/omi0/ocmb0";
constexpr auto core_str   = "pib/perv39/eq7/fc1/core1";

// Local implementation of this function.
namespace analyzer
{

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

// Helper function to get the root cause chip target path from the service data.
std::string __getRootCauseChipPath(const ServiceData& i_sd)
{
    return std::string{(const char*)i_sd.getRootCause().getChip().getChip()};
}

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

// Helper function to get a unit target path from the given unit path, which is
// a devtree path relative the the containing chip. An empty string indicates
// the chip target path should be returned.
std::string __getUnitPath(const std::string& i_chipPath,
                          const std::string& i_unitPath)
{
    auto path = i_chipPath; // default, if i_unitPath is empty

    if (!i_unitPath.empty())
    {
        path += "/" + i_unitPath;
    }

    return path;
}

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

// Helper function to get the connected target Path on the other side of the
// given bus.
std::tuple<std::string, std::string>
    __getConnectedPath(const std::string& i_rxPath,
                       const callout::BusType& i_busType)
{
    std::string txUnitPath{};
    std::string txChipPath{};

    // Need to get the target type from the RX path.
    const std::regex re{"(/proc0)(.*)/([a-z]+)([0-9]+)"};
    std::smatch match;
    std::regex_match(i_rxPath, match, re);
    assert(5 == match.size());
    std::string rxType = match[3].str();

    if (callout::BusType::SMP_BUS == i_busType && "smpgroup" == rxType)
    {
        // Use the RX unit path on a different processor.
        txUnitPath = "/proc1" + match[2].str() + "/" + rxType + match[4].str();
        txChipPath = "/proc1";
    }
    else if (callout::BusType::OMI_BUS == i_busType && "omi" == rxType)
    {
        // Append the OCMB to the RX path.
        txUnitPath = i_rxPath + "/ocmb0";
        txChipPath = txUnitPath;
    }
    else if (callout::BusType::OMI_BUS == i_busType && "ocmb" == rxType)
    {
        // Strip the OCMB off of the RX path.
        txUnitPath = match[1].str() + match[2].str();
        txChipPath = "/proc0";
    }
    else
    {
        // This would be a code bug.
        throw std::logic_error("Unsupported config: i_rxTarget=" + i_rxPath +
                               " i_busType=" + i_busType.getString());
    }

    assert(!txUnitPath.empty()); // just in case we missed something above

    return std::make_tuple(txUnitPath, txChipPath);
}

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

void __calloutTarget(ServiceData& io_sd, const std::string& i_locCode,
                     const callout::Priority& i_priority, bool i_guard,
                     const std::string& i_guardPath)
{
    nlohmann::json callout;
    callout["LocationCode"] = i_locCode;
    callout["Priority"]     = i_priority.getUserDataString();
    callout["Deconfigured"] = false;
    callout["Guarded"]      = false; // default

    // Check if guard info should be added.
    if (i_guard)
    {
        auto guardType = io_sd.queryGuardPolicy();

        if (!(callout::GuardType::NONE == guardType))
        {
            callout["Guarded"]    = true;
            callout["Guard Path"] = i_guardPath;
            callout["Guard Type"] = guardType.getString();
        }
    }

    io_sd.addCallout(callout);
}

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

void __calloutBackplane(ServiceData& io_sd, const callout::Priority& i_priority)
{
    // TODO: There isn't a device tree object for this. So will need to hardcode
    //       the location code for now. In the future, we will need a mechanism
    //       to make this data driven.

    nlohmann::json callout;
    callout["LocationCode"] = "P0";
    callout["Priority"]     = i_priority.getUserDataString();
    callout["Deconfigured"] = false;
    callout["Guarded"]      = false;
    io_sd.addCallout(callout);
}

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

void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
{
    // Get the location code and entity path for this target.
    auto locCode    = __getRootCauseChipPath(io_sd);
    auto entityPath = __getUnitPath(locCode, iv_unitPath);

    // Add the actual callout to the service data.
    __calloutTarget(io_sd, locCode, iv_priority, iv_guard, entityPath);

    // Add the callout FFDC to the service data.
    nlohmann::json ffdc;
    ffdc["Callout Type"] = "Hardware Callout";
    ffdc["Target"]       = entityPath;
    ffdc["Priority"]     = iv_priority.getRegistryString();
    ffdc["Guard"]        = iv_guard;
    io_sd.addCalloutFFDC(ffdc);
}

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

void ConnectedCalloutResolution::resolve(ServiceData& io_sd) const
{
    // Get the chip target path from the root cause signature.
    auto chipPath = __getRootCauseChipPath(io_sd);

    // Get the endpoint target path for the receiving side of the bus.
    auto rxPath = __getUnitPath(chipPath, iv_unitPath);

    // Get the endpoint target path for the transfer side of the bus.
    auto txPath = __getConnectedPath(rxPath, iv_busType);

    // Callout the TX endpoint.
    __calloutTarget(io_sd, std::get<1>(txPath), iv_priority, iv_guard,
                    std::get<0>(txPath));

    // Add the callout FFDC to the service data.
    nlohmann::json ffdc;
    ffdc["Callout Type"] = "Connected Callout";
    ffdc["Bus Type"]     = iv_busType.getString();
    ffdc["Target"]       = std::get<0>(txPath);
    ffdc["Priority"]     = iv_priority.getRegistryString();
    ffdc["Guard"]        = iv_guard;
    io_sd.addCalloutFFDC(ffdc);
}

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

void BusCalloutResolution::resolve(ServiceData& io_sd) const
{
    // Get the chip target path from the root cause signature.
    auto chipPath = __getRootCauseChipPath(io_sd);

    // Get the endpoint target path for the receiving side of the bus.
    auto rxPath = __getUnitPath(chipPath, iv_unitPath);

    // Get the endpoint target path for the transfer side of the bus.
    auto txPath = __getConnectedPath(rxPath, iv_busType);

    // Callout the RX endpoint.
    __calloutTarget(io_sd, chipPath, iv_priority, iv_guard, rxPath);

    // Callout the TX endpoint.
    __calloutTarget(io_sd, std::get<1>(txPath), iv_priority, iv_guard,
                    std::get<0>(txPath));

    // Callout everything else in between.
    // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
    __calloutBackplane(io_sd, iv_priority);

    // Add the callout FFDC to the service data.
    nlohmann::json ffdc;
    ffdc["Callout Type"] = "Bus Callout";
    ffdc["Bus Type"]     = iv_busType.getString();
    ffdc["RX Target"]    = rxPath;
    ffdc["TX Target"]    = std::get<0>(txPath);
    ffdc["Priority"]     = iv_priority.getRegistryString();
    ffdc["Guard"]        = iv_guard;
    io_sd.addCalloutFFDC(ffdc);
}

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

void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
{
    // Add the actual callout to the service data.
    nlohmann::json callout;
    callout["Procedure"] = iv_procedure.getString();
    callout["Priority"]  = iv_priority.getUserDataString();
    io_sd.addCallout(callout);

    // Add the callout FFDC to the service data.
    nlohmann::json ffdc;
    ffdc["Callout Type"] = "Procedure Callout";
    ffdc["Procedure"]    = iv_procedure.getString();
    ffdc["Priority"]     = iv_priority.getRegistryString();
    io_sd.addCalloutFFDC(ffdc);
}

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

void ClockCalloutResolution::resolve(ServiceData& io_sd) const
{
    // Callout the clock target.
    // TODO: For P10, the callout is simply the backplane. Also, there are no
    //       clock targets in the device tree. So at the moment there is no
    //       guard support for clock targets.
    __calloutBackplane(io_sd, iv_priority);

    // Add the callout FFDC to the service data.
    // TODO: Add the target and guard type if guard is ever supported.
    nlohmann::json ffdc;
    ffdc["Callout Type"] = "Clock Callout";
    ffdc["Clock Type"]   = iv_clockType.getString();
    ffdc["Priority"]     = iv_priority.getRegistryString();
    io_sd.addCalloutFFDC(ffdc);
}

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

} // namespace analyzer

using namespace analyzer;

TEST(Resolution, TestSet1)
{
    // Create a few resolutions
    auto c1 = std::make_shared<HardwareCalloutResolution>(
        proc_str, callout::Priority::HIGH, false);

    auto c2 = std::make_shared<HardwareCalloutResolution>(
        omi_str, callout::Priority::MED_A, true);

    auto c3 = std::make_shared<HardwareCalloutResolution>(
        core_str, callout::Priority::MED, true);

    auto c4 = std::make_shared<ProcedureCalloutResolution>(
        callout::Procedure::NEXTLVL, callout::Priority::LOW);

    auto c5 = std::make_shared<ClockCalloutResolution>(
        callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::LOW, false);

    // l1 = (c1, c2, c5)
    auto l1 = std::make_shared<ResolutionList>();
    l1->push(c1);
    l1->push(c2);
    l1->push(c5);

    // l2 = (c4, c3, c1, c2, c5)
    auto l2 = std::make_shared<ResolutionList>();
    l2->push(c4);
    l2->push(c3);
    l2->push(l1);

    // Get some ServiceData objects
    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd1{sig, AnalysisType::SYSTEM_CHECKSTOP};
    ServiceData sd2{sig, AnalysisType::TERMINATE_IMMEDIATE};

    // Resolve
    l1->resolve(sd1);
    l2->resolve(sd2);

    // Start verifying
    nlohmann::json j{};
    std::string s{};

    j = sd1.getCalloutList();
    s = R"([
    {
        "Deconfigured": false,
        "Guarded": false,
        "LocationCode": "/proc0",
        "Priority": "H"
    },
    {
        "Deconfigured": false,
        "Guarded": false,
        "LocationCode": "P0",
        "Priority": "L"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    j = sd2.getCalloutList();
    s = R"([
    {
        "Priority": "L",
        "Procedure": "next_level_support"
    },
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv39/eq7/fc1/core1",
        "Guard Type": "GARD_Predictive",
        "Guarded": true,
        "LocationCode": "/proc0",
        "Priority": "H"
    },
    {
        "Deconfigured": false,
        "Guarded": false,
        "LocationCode": "P0",
        "Priority": "L"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}

TEST(Resolution, HardwareCallout)
{
    auto c1 = std::make_shared<HardwareCalloutResolution>(
        omi_str, callout::Priority::MED_A, true);

    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP};

    c1->resolve(sd);

    nlohmann::json j{};
    std::string s{};

    // Callout list
    j = sd.getCalloutList();
    s = R"([
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc0",
        "Priority": "A"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    // Callout FFDC
    j = sd.getCalloutFFDC();
    s = R"([
    {
        "Callout Type": "Hardware Callout",
        "Guard": true,
        "Priority": "medium_group_A",
        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}

TEST(Resolution, ConnectedCallout)
{
    auto c1 = std::make_shared<ConnectedCalloutResolution>(
        callout::BusType::SMP_BUS, iolink_str, callout::Priority::MED_A, true);

    auto c2 = std::make_shared<ConnectedCalloutResolution>(
        callout::BusType::OMI_BUS, ocmb_str, callout::Priority::MED_B, true);

    auto c3 = std::make_shared<ConnectedCalloutResolution>(
        callout::BusType::OMI_BUS, omi_str, callout::Priority::MED_C, true);

    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP};

    nlohmann::json j{};
    std::string s{};

    c1->resolve(sd);
    c2->resolve(sd);
    c3->resolve(sd);

    // Callout list
    j = sd.getCalloutList();
    s = R"([
    {
        "Deconfigured": false,
        "Guard Path": "/proc1/pib/perv24/pauc0/iohs0/smpgroup0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc1",
        "Priority": "A"
    },
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc0",
        "Priority": "B"
    },
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
        "Priority": "C"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    // Callout FFDC
    j = sd.getCalloutFFDC();
    s = R"([
    {
        "Bus Type": "SMP_BUS",
        "Callout Type": "Connected Callout",
        "Guard": true,
        "Priority": "medium_group_A",
        "Target": "/proc1/pib/perv24/pauc0/iohs0/smpgroup0"
    },
    {
        "Bus Type": "OMI_BUS",
        "Callout Type": "Connected Callout",
        "Guard": true,
        "Priority": "medium_group_B",
        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
    },
    {
        "Bus Type": "OMI_BUS",
        "Callout Type": "Connected Callout",
        "Guard": true,
        "Priority": "medium_group_C",
        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}

TEST(Resolution, BusCallout)
{
    auto c1 = std::make_shared<HardwareCalloutResolution>(
        omi_str, callout::Priority::MED_A, true);

    auto c2 = std::make_shared<ConnectedCalloutResolution>(
        callout::BusType::OMI_BUS, omi_str, callout::Priority::MED_A, true);

    auto c3 = std::make_shared<BusCalloutResolution>(
        callout::BusType::OMI_BUS, omi_str, callout::Priority::LOW, false);

    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP};

    nlohmann::json j{};
    std::string s{};

    c1->resolve(sd);
    c2->resolve(sd);
    c3->resolve(sd);

    // Callout list
    j = sd.getCalloutList();
    s = R"([
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc0",
        "Priority": "A"
    },
    {
        "Deconfigured": false,
        "Guard Path": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
        "Guard Type": "GARD_Unrecoverable",
        "Guarded": true,
        "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
        "Priority": "A"
    },
    {
        "Deconfigured": false,
        "Guarded": false,
        "LocationCode": "P0",
        "Priority": "L"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    // Callout FFDC
    j = sd.getCalloutFFDC();
    s = R"([
    {
        "Callout Type": "Hardware Callout",
        "Guard": true,
        "Priority": "medium_group_A",
        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
    },
    {
        "Bus Type": "OMI_BUS",
        "Callout Type": "Connected Callout",
        "Guard": true,
        "Priority": "medium_group_A",
        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
    },
    {
        "Bus Type": "OMI_BUS",
        "Callout Type": "Bus Callout",
        "Guard": false,
        "Priority": "low",
        "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
        "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}

TEST(Resolution, ClockCallout)
{
    auto c1 = std::make_shared<ClockCalloutResolution>(
        callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::HIGH, false);

    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP};

    c1->resolve(sd);

    nlohmann::json j{};
    std::string s{};

    // Callout list
    j = sd.getCalloutList();
    s = R"([
    {
        "Deconfigured": false,
        "Guarded": false,
        "LocationCode": "P0",
        "Priority": "H"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    // Callout FFDC
    j = sd.getCalloutFFDC();
    s = R"([
    {
        "Callout Type": "Clock Callout",
        "Clock Type": "OSC_REF_CLOCK_1",
        "Priority": "high"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}

TEST(Resolution, ProcedureCallout)
{
    auto c1 = std::make_shared<ProcedureCalloutResolution>(
        callout::Procedure::NEXTLVL, callout::Priority::LOW);

    libhei::Chip chip{chip_str, 0xdeadbeef};
    libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP};
    ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP};

    c1->resolve(sd);

    nlohmann::json j{};
    std::string s{};

    // Callout list
    j = sd.getCalloutList();
    s = R"([
    {
        "Priority": "L",
        "Procedure": "next_level_support"
    }
])";
    EXPECT_EQ(s, j.dump(4));

    // Callout FFDC
    j = sd.getCalloutFFDC();
    s = R"([
    {
        "Callout Type": "Procedure Callout",
        "Priority": "low",
        "Procedure": "next_level_support"
    }
])";
    EXPECT_EQ(s, j.dump(4));
}
