#include <isolator/hei_isolation_node.hpp>
#include <util/hei_bit_string.hpp>

namespace libhei
{

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

bool IsolationNode::analyze(const Chip& i_chip, AttentionType_t i_attnType,
                            IsolationData& io_isoData) const
{
    bool o_activeAttn = false; // Initially, assume no active attentions.

    // Keep track of nodes that have been analyzed to avoid cyclic isolation.
    pushIsolationStack();

    // Capture all registers for this node.
    for (const auto& hwReg : iv_capRegs)
    {
        // Read the register (adds BitString to register cache).
        if (hwReg->read(i_chip))
        {
            // The register read failed.
            // TODO: Would be nice to add SCOM errors to the log just in case
            //       traces are not available.
            // TODO: This trace could be redundant with the user application,
            //       which will have more information on the actual chip that
            //       failed anyway. Leaving it commented out for now until the
            //       SCOM errors are added to the log.
            // HEI_ERR("register read failed on chip type=0x%0" PRIx32
            //         "address=0x%0" PRIx64,
            //         i_chip.getType(), hwReg->getAddress());
        }
        else
        {
            // Add to the FFDC.
            io_isoData.addRegister(i_chip, hwReg->getId(), hwReg->getInstance(),
                                   hwReg->getBitString(i_chip));
        }
    }

    // Get the rule for this attention type.
    auto rule_itr = iv_rules.find(i_attnType);

    // It is possible that a rule does not exist. The likely scenario is that
    // this node is intended to only gather FFDC for a specific bit in the
    // parent node.
    if (iv_rules.end() != rule_itr)
    {
        // Get the returned BitString for this rule.
        const BitString* bs = rule_itr->second->getBitString(i_chip);

        // Ensure this BitString is not longer than the maximum bit field.
        HEI_ASSERT(bs->getBitLen() <= (1 << (sizeof(BitPosition_t) * 8)));

        // Find all active bits for this rule.
        for (BitPosition_t bit = 0; bit < bs->getBitLen(); bit++)
        {
            // Continue to the next bit if not active.
            if (!bs->isBitSet(bit))
                continue;

            // At least one active bit was found.
            o_activeAttn = true;

            // Determine if this attention originated from another register or
            // if it is a leaf in the isolation tree.
            auto child_itr = iv_children.find(bit);
            if (iv_children.end() != child_itr)
            {
                // This bit was driven from an attention from another register.
                // Continue down the isolation tree to look for more attentions.
                bool attnFound =
                    child_itr->second->analyze(i_chip, i_attnType, io_isoData);
                if (!attnFound)
                {
                    // It is possible the child node is only intended for FFDC.
                    // See comment near the check for a valid rule above.
                    // Otherwise, it is possible something went wrong. If there
                    // should have been an active attention, it's possible there
                    // is a bug in the Chip Data File. Or, it is also possible
                    // some other piece of code is clearing the attention before
                    // this code is able to analyze it. Another possibility is
                    // that the hardware it not behaving as expected. Since we
                    // really don't know what happened, we should not assert.
                    // Instead, add this bit's signature to io_isoData. If there
                    // are no other active attentions, the user application
                    // could use this signature to help determine, and
                    // circumvent, the isolation problem.
                    io_isoData.addSignature(
                        Signature{i_chip, iv_id, iv_instance, bit, i_attnType});
                }
            }
            else
            {
                // We have reached a leaf in the isolation tree. Add this bit's
                // signature to io_isoData.
                io_isoData.addSignature(
                    Signature{i_chip, iv_id, iv_instance, bit, i_attnType});
            }
        }
    }

    // Analysis is complete on this node. So remove it from cv_isolationStack.
    popIsolationStack();

    return o_activeAttn;
}

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

void IsolationNode::addCaptureRegister(HardwareRegister::ConstPtr i_hwReg)
{
    HEI_ASSERT(i_hwReg); // should not be null

    // If the register already exists, ignore it. Otherwise, add it to the list.
    auto itr = std::find(iv_capRegs.begin(), iv_capRegs.end(), i_hwReg);
    if (iv_capRegs.end() == itr)
    {
        iv_capRegs.push_back(i_hwReg);
    }
}

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

void IsolationNode::addRule(AttentionType_t i_attnType,
                            Register::ConstPtr i_rule)
{
    HEI_ASSERT(i_rule); // should not be null

    auto ret = iv_rules.emplace(i_attnType, i_rule);

    // If an entry already existed, it must point to the same object.
    HEI_ASSERT(ret.second || (ret.first->second == i_rule));
}

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

void IsolationNode::addChild(uint8_t i_bit, ConstPtr i_child)
{
    HEI_ASSERT(i_child); // should not be null

    auto ret = iv_children.emplace(i_bit, i_child);

    // If an entry already existed, it must point to the same object.
    HEI_ASSERT(ret.second || (ret.first->second == i_child));
}

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

std::vector<const IsolationNode*> IsolationNode::cv_isolationStack{};

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

void IsolationNode::pushIsolationStack() const
{
    // Ensure this node does not already exist in cv_isolationStack.
    auto itr =
        std::find(cv_isolationStack.begin(), cv_isolationStack.end(), this);
    HEI_ASSERT(cv_isolationStack.end() == itr);

    // Push to node to the stack.
    cv_isolationStack.push_back(this);
}

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

} // end namespace libhei
