//------------------------------------------------------------------------------
// IMPORTANT:
// This file will be built in CI test and should work out-of-the-box in CI test
// with use of the fake device tree. Any functions that require addition support
// to simulate in CI test should be put in `pdbg_no_sim.cpp`.
//------------------------------------------------------------------------------

#include <assert.h>
#include <config.h>

#include <hei_main.hpp>
#include <nlohmann/json.hpp>
#include <util/dbus.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>

#include <filesystem>
#include <fstream>
#include <string>

#ifdef CONFIG_PHAL_API
#include <attributes_info.H>
#endif

using namespace analyzer;

namespace fs = std::filesystem;

namespace util
{

namespace pdbg
{

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

pdbg_target* getTrgt(const libhei::Chip& i_chip)
{
    return (pdbg_target*)i_chip.getChip();
}

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

pdbg_target* getTrgt(const std::string& i_path)
{
    return pdbg_target_from_path(nullptr, i_path.c_str());
}

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

const char* getPath(pdbg_target* i_trgt)
{
    return pdbg_target_path(i_trgt);
}

const char* getPath(const libhei::Chip& i_chip)
{
    return getPath(getTrgt(i_chip));
}

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

uint32_t getChipPos(pdbg_target* i_trgt)
{
    uint32_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_FAPI_POS", 4, 1, &attr);
    return attr;
}

uint32_t getChipPos(const libhei::Chip& i_chip)
{
    return getChipPos(getTrgt(i_chip));
}

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

uint8_t getUnitPos(pdbg_target* i_trgt)
{
    uint8_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_UNIT_POS", 1, 1, &attr);
    return attr;
}

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

uint8_t getTrgtType(pdbg_target* i_trgt)
{
    uint8_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_TYPE", 1, 1, &attr);
    return attr;
}

uint8_t getTrgtType(const libhei::Chip& i_chip)
{
    return getTrgtType(getTrgt(i_chip));
}

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

pdbg_target* getParentChip(pdbg_target* i_unitTarget)
{
    assert(nullptr != i_unitTarget);

    // Check if the given target is already a chip.
    auto targetType = getTrgtType(i_unitTarget);
    if (TYPE_PROC == targetType || TYPE_OCMB == targetType)
    {
        return i_unitTarget; // simply return the given target
    }

    // Check if this unit is on an OCMB.
    pdbg_target* parentChip = pdbg_target_parent("ocmb", i_unitTarget);

    // If not on the OCMB, check if this unit is on a PROC.
    if (nullptr == parentChip)
    {
        parentChip = pdbg_target_parent("proc", i_unitTarget);
    }

    // There should always be a parent chip. Throw an error if not found.
    if (nullptr == parentChip)
    {
        throw std::logic_error("No parent chip found: i_unitTarget=" +
                               std::string{getPath(i_unitTarget)});
    }

    return parentChip;
}

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

pdbg_target* getParentProcessor(pdbg_target* i_target)
{
    assert(nullptr != i_target);

    // Check if the given target is already a processor chip.
    if (TYPE_PROC == getTrgtType(i_target))
    {
        return i_target; // simply return the given target
    }

    // Get the parent processor chip.
    pdbg_target* parentChip = pdbg_target_parent("proc", i_target);

    // There should always be a parent chip. Throw an error if not found.
    if (nullptr == parentChip)
    {
        throw std::logic_error(
            "No parent chip found: i_target=" + std::string{getPath(i_target)});
    }

    return parentChip;
}

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

pdbg_target* getChipUnit(pdbg_target* i_parentChip, TargetType_t i_unitType,
                         uint8_t i_unitPos)
{
    assert(nullptr != i_parentChip);

    auto parentType = getTrgtType(i_parentChip);

    std::string devTreeType{};

    if (TYPE_PROC == parentType)
    {
        // clang-format off
        static const std::map<TargetType_t, std::string> m =
        {
            {TYPE_MC,     "mc"      },
            {TYPE_MCC,    "mcc"     },
            {TYPE_OMI,    "omi"     },
            {TYPE_OMIC,   "omic"    },
            {TYPE_PAUC,   "pauc"    },
            {TYPE_PAU,    "pau"     },
            {TYPE_NMMU,   "nmmu"    },
            {TYPE_IOHS,   "iohs"    },
            {TYPE_IOLINK, "smpgroup"},
            {TYPE_EQ,     "eq"      },
            {TYPE_CORE,   "core"    },
            {TYPE_PEC,    "pec"     },
            {TYPE_PHB,    "phb"     },
            {TYPE_NX,     "nx"      },
        };
        // clang-format on

        devTreeType = m.at(i_unitType);
    }
    else if (TYPE_OCMB == parentType)
    {
        // clang-format off
        static const std::map<TargetType_t, std::string> m =
        {
            {TYPE_MEM_PORT, "mem_port"},
        };
        // clang-format on

        devTreeType = m.at(i_unitType);
    }
    else
    {
        throw std::logic_error(
            "Unexpected parent chip: " + std::string{getPath(i_parentChip)});
    }

    // Iterate all children of the parent and match the unit position.
    pdbg_target* unitTarget = nullptr;
    pdbg_for_each_target(devTreeType.c_str(), i_parentChip, unitTarget)
    {
        if (nullptr != unitTarget && i_unitPos == getUnitPos(unitTarget))
        {
            break; // found it
        }
    }

    // Print a warning if the target unit is not found, but don't throw an
    // error.  Instead let the calling code deal with the it.
    if (nullptr == unitTarget)
    {
        trace::err("No unit target found: i_parentChip=%s i_unitType=0x%02x "
                   "i_unitPos=%u",
                   getPath(i_parentChip), i_unitType, i_unitPos);
    }

    return unitTarget;
}

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

pdbg_target* getTargetAcrossBus(pdbg_target* i_rxTarget)
{
    assert(nullptr != i_rxTarget);

    // Validate target type
    auto rxType = util::pdbg::getTrgtType(i_rxTarget);
    assert(util::pdbg::TYPE_IOLINK == rxType ||
           util::pdbg::TYPE_IOHS == rxType);

    pdbg_target* o_peerTarget;
    fs::path filePath;

    // Open the appropriate data file depending on machine type
    util::dbus::MachineType machineType = util::dbus::getMachineType();
    switch (machineType)
    {
        // Rainier 4U
        case util::dbus::MachineType::Rainier_2S4U:
        case util::dbus::MachineType::Rainier_1S4U:
            filePath =
                fs::path{PACKAGE_DIR "util-data/peer-targets-rainier-4u.json"};
            break;
        // Rainier 2U
        case util::dbus::MachineType::Rainier_2S2U:
        case util::dbus::MachineType::Rainier_1S2U:
            filePath =
                fs::path{PACKAGE_DIR "util-data/peer-targets-rainier-2u.json"};
            break;
        // Everest
        case util::dbus::MachineType::Everest:
            filePath =
                fs::path{PACKAGE_DIR "util-data/peer-targets-everest.json"};
            break;
        // Bonnell
        case util::dbus::MachineType::Bonnell:
            filePath =
                fs::path{PACKAGE_DIR "util-data/peer-targets-bonnell.json"};
            break;
        default:
            trace::err("Invalid machine type found %d",
                       static_cast<uint8_t>(machineType));
            break;
    }

    std::ifstream file{filePath};
    assert(file.good());

    try
    {
        auto trgtMap = nlohmann::json::parse(file);
        std::string rxPath = util::pdbg::getPath(i_rxTarget);
        std::string peerPath = trgtMap.at(rxPath).get<std::string>();

        o_peerTarget = util::pdbg::getTrgt(peerPath);
    }
    catch (...)
    {
        trace::err("Failed to parse file: %s", filePath.string().c_str());
        throw;
    }

    return o_peerTarget;
}

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

pdbg_target* getConnectedTarget(pdbg_target* i_rxTarget,
                                const callout::BusType& i_busType)
{
    assert(nullptr != i_rxTarget);

    pdbg_target* txTarget = nullptr;

    auto rxType = util::pdbg::getTrgtType(i_rxTarget);
    std::string rxPath = util::pdbg::getPath(i_rxTarget);

    if (callout::BusType::SMP_BUS == i_busType &&
        util::pdbg::TYPE_IOLINK == rxType)
    {
        txTarget = getTargetAcrossBus(i_rxTarget);
    }
    else if (callout::BusType::SMP_BUS == i_busType &&
             util::pdbg::TYPE_IOHS == rxType)
    {
        txTarget = getTargetAcrossBus(i_rxTarget);
    }
    else if (callout::BusType::OMI_BUS == i_busType &&
             util::pdbg::TYPE_OMI == rxType)
    {
        // This is a bit clunky. The pdbg APIs only give us the ability to
        // iterate over the children instead of just returning a list. So
        // we'll push all the children to a list and go from there.
        std::vector<pdbg_target*> childList;

        pdbg_target* childTarget = nullptr;
        pdbg_for_each_target("ocmb", i_rxTarget, childTarget)
        {
            if (nullptr != childTarget)
            {
                childList.push_back(childTarget);
            }
        }

        // We know there should only be one OCMB per OMI.
        if (1 != childList.size())
        {
            throw std::logic_error("Invalid child list size for " + rxPath);
        }

        // Get the connected target.
        txTarget = childList.front();
    }
    else if (callout::BusType::OMI_BUS == i_busType &&
             util::pdbg::TYPE_OCMB == rxType)
    {
        txTarget = pdbg_target_parent("omi", i_rxTarget);
        if (nullptr == txTarget)
        {
            throw std::logic_error("No parent OMI found for " + rxPath);
        }
    }
    else
    {
        // This would be a code bug.
        throw std::logic_error("Unsupported config: i_rxTarget=" + rxPath +
                               " i_busType=" + i_busType.getString());
    }

    assert(nullptr != txTarget); // just in case we missed something above

    return txTarget;
}

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

pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
{
    // The input target must be a processor.
    assert(TYPE_PROC == getTrgtType(i_procTrgt));

    // Get the pib path.
    char path[16];
    sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));

    // Return the pib target.
    pdbg_target* pibTrgt = pdbg_target_from_path(nullptr, path);
    assert(nullptr != pibTrgt);

    return pibTrgt;
}

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

pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt)
{
    // The input target must be a processor.
    assert(TYPE_PROC == getTrgtType(i_procTrgt));

    // Get the fsi path.
    char path[16];
    sprintf(path, "/proc%d/fsi", pdbg_target_index(i_procTrgt));

    // Return the fsi target.
    pdbg_target* fsiTrgt = pdbg_target_from_path(nullptr, path);
    assert(nullptr != fsiTrgt);

    return fsiTrgt;
}

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

// IMPORTANT:
// The ATTR_CHIP_ID attribute will be synced from Hostboot to the BMC at
// some point during the IPL. It is possible that this information is needed
// before the sync occurs, in which case the value will return 0.
uint32_t __getChipId(pdbg_target* i_trgt)
{
    uint32_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_ID", 4, 1, &attr);
    return attr;
}

// IMPORTANT:
// The ATTR_EC attribute will be synced from Hostboot to the BMC at some
// point during the IPL. It is possible that this information is needed
// before the sync occurs, in which case the value will return 0.
uint8_t __getChipEc(pdbg_target* i_trgt)
{
    uint8_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_EC", 1, 1, &attr);
    return attr;
}

uint32_t __getChipIdEc(pdbg_target* i_trgt)
{
    auto chipId = __getChipId(i_trgt);
    auto chipEc = __getChipEc(i_trgt);

    if (((0 == chipId) || (0 == chipEc)) && (TYPE_PROC == getTrgtType(i_trgt)))
    {
        // There is a special case where the model/level attributes have not
        // been initialized in the devtree. This is possible on the epoch
        // IPL where an attention occurs before Hostboot is able to update
        // the devtree information on the BMC. It may is still possible to
        // get this information from chips with CFAM access (i.e. a
        // processor) via the CFAM chip ID register.

        uint32_t val = 0;
        if (0 == getCfam(i_trgt, 0x100a, val))
        {
            chipId = ((val & 0x0F0FF000) >> 12);
            chipEc = ((val & 0xF0000000) >> 24) | ((val & 0x00F00000) >> 20);
        }
    }

    return ((chipId & 0xffff) << 16) | (chipEc & 0xff);
}

void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
               libhei::ChipType_t i_type)
{
    // Trace each chip for debug. It is important to show the type just in
    // case the model/EC does not exist. See note below.
    trace::inf("Chip found: type=0x%08" PRIx32 " chip=%s", i_type,
               getPath(i_trgt));

    if (0 == i_type)
    {
        // This is a special case. See the details in __getChipIdEC(). There
        // is nothing more we can do with this chip since we don't know what
        // it is. So ignore the chip for now.
    }
    else
    {
        o_chips.emplace_back(i_trgt, i_type);
    }
}

// Should ignore OCMBs that have been masked on the processor side of the bus.
bool __isMaskedOcmb(const libhei::Chip& i_chip)
{
    // TODO: This function only works for P10 processors will need to update for
    // subsequent chips.

    // Map of MCC target position to DSTL_FIR_MASK address.
    static const std::map<unsigned int, uint64_t> addrs = {
        {0, 0x0C010D03}, {1, 0x0C010D43}, {2, 0x0D010D03}, {3, 0x0D010D43},
        {4, 0x0E010D03}, {5, 0x0E010D43}, {6, 0x0F010D03}, {7, 0x0F010D43},
    };

    auto ocmb = getTrgt(i_chip);

    // Confirm this chip is an OCMB.
    if (TYPE_OCMB != getTrgtType(ocmb))
    {
        return false;
    }

    // Get the connected MCC target on the processor chip.
    auto mcc = pdbg_target_parent("mcc", ocmb);
    if (nullptr == mcc)
    {
        throw std::logic_error(
            "No parent MCC found for " + std::string{getPath(ocmb)});
    }

    // Read the associated DSTL_FIR_MASK.
    uint64_t val = 0;
    if (getScom(getParentChip(mcc), addrs.at(getUnitPos(mcc)), val))
    {
        // Just let this go. The SCOM code will log the error.
        return false;
    }

    // The DSTL_FIR has bits for each of the two memory channels on the MCC.
    auto chnlPos = getChipPos(ocmb) % 2;

    // Channel 0 => bits 0-3, channel 1 => bits 4-7.
    auto mask = (val >> (60 - (4 * chnlPos))) & 0xf;

    // Return true if the mask is set to all 1's.
    if (0xf == mask)
    {
        trace::inf("OCMB masked on processor side of bus: %s", getPath(ocmb));
        return true;
    }

    return false; // default
}

void getActiveChips(std::vector<libhei::Chip>& o_chips)
{
    o_chips.clear();

    // Iterate each processor.
    pdbg_target* procTrgt;
    pdbg_for_each_class_target("proc", procTrgt)
    {
        // We cannot use the proc target to determine if the chip is active.
        // There is some design limitation in pdbg that requires the proc
        // targets to always be active. Instead, we must get the associated
        // pib target and check if it is active.

        // Active processors only.
        if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
            continue;

        // Add the processor to the list.
        __addChip(o_chips, procTrgt, __getChipIdEc(procTrgt));

        // Iterate the connected OCMBs, if they exist.
        pdbg_target* ocmbTrgt;
        pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
        {
            // Active OCMBs only.
            if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
                continue;

            // Add the OCMB to the list.
            __addChip(o_chips, ocmbTrgt, __getChipIdEc(ocmbTrgt));
        }
    }

    // Ignore OCMBs that have been masked on the processor side of the bus.
    o_chips.erase(
        std::remove_if(o_chips.begin(), o_chips.end(), __isMaskedOcmb),
        o_chips.end());
}

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

void getActiveProcessorChips(std::vector<pdbg_target*>& o_chips)
{
    o_chips.clear();

    pdbg_target* procTrgt;
    pdbg_for_each_class_target("proc", procTrgt)
    {
        // We cannot use the proc target to determine if the chip is active.
        // There is some design limitation in pdbg that requires the proc
        // targets to always be active. Instead, we must get the associated pib
        // target and check if it is active.

        if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
            continue;

        o_chips.push_back(procTrgt);
    }
}

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

pdbg_target* getPrimaryProcessor()
{
    // TODO: For at least P10, the primary processor (the one connected
    // directly
    //       to the BMC), will always be PROC 0. We will need to update this
    //       later if we ever support an alternate primary processor.
    return getTrgt("/proc0");
}

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

bool queryHardwareAnalysisSupported()
{
    // Hardware analysis is only supported on P10 systems and up.
    return (PDBG_PROC_P9 < pdbg_get_proc());
}

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

std::string getLocationCode(pdbg_target* trgt)
{
    if (nullptr == trgt)
    {
        // Either the path is wrong or the attribute doesn't exist.
        return std::string{};
    }

#ifdef CONFIG_PHAL_API

    ATTR_LOCATION_CODE_Type val;
    if (DT_GET_PROP(ATTR_LOCATION_CODE, trgt, val))
    {
        // Get the immediate parent in the devtree path and try again.
        return getLocationCode(pdbg_target_parent(nullptr, trgt));
    }

    // Attribute found.
    return std::string{val};

#else

    return std::string{getPath(trgt)};

#endif
}

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

std::string getPhysDevPath(pdbg_target* trgt)
{
    if (nullptr == trgt)
    {
        // Either the path is wrong or the attribute doesn't exist.
        return std::string{};
    }

#ifdef CONFIG_PHAL_API

    ATTR_PHYS_DEV_PATH_Type val;
    if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, trgt, val))
    {
        // Get the immediate parent in the devtree path and try again.
        return getPhysDevPath(pdbg_target_parent(nullptr, trgt));
    }

    // Attribute found.
    return std::string{val};

#else

    return std::string{getPath(trgt)};

#endif
}

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

std::vector<uint8_t> getPhysBinPath(pdbg_target* target)
{
    std::vector<uint8_t> binPath;

    if (nullptr != target)
    {
#ifdef CONFIG_PHAL_API

        ATTR_PHYS_BIN_PATH_Type value;
        if (DT_GET_PROP(ATTR_PHYS_BIN_PATH, target, value))
        {
            // The attrirbute for this target does not exist. Get the
            // immediate parent in the devtree path and try again. Note that
            // if there is no parent target, nullptr will be returned and
            // that will be checked above.
            return getPhysBinPath(pdbg_target_parent(nullptr, target));
        }

        // Attribute was found. Copy the attribute array to the returned
        // vector. Note that the reason we return the vector instead of just
        // returning the array is because the array type and details only
        // exists in this specific configuration.
        binPath.insert(binPath.end(), value, value + sizeof(value));

#endif
    }

    return binPath;
}

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

} // namespace pdbg

} // namespace util
