#include <isolator/hei_isolation_node.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();

    // A rule for i_attnType must exist.
    auto rule_itr = iv_rules.find(i_attnType);
    HEI_ASSERT(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() <= sizeof(RegisterBit_t) * 8);

    // Find all active bits for this rule.
    for (RegisterBit_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)
            {
                // Something went wrong. 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_hwReg.getId(),
                                                    iv_hwReg.getInstance(),
                                                    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_hwReg.getId(),
                                                iv_hwReg.getInstance(),
                                                bit, i_attnType });
        }
    }

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

    return o_activeAttn;
}

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

void IsolationNode::addRule(AttentionType_t i_attnType, const Register* i_rule)
{
    // A rule for this attention type should not already exist.
    HEI_ASSERT(iv_rules.end() == iv_rules.find(i_attnType));

    // The rule should not be null.
    HEI_ASSERT(nullptr != i_rule);

    // Add the new rule.
    iv_rules[i_attnType] = i_rule;
}

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

void IsolationNode::addChild(uint8_t i_bit, const IsolationNode* i_child)
{
    // An entry for this bit should not already exist.
    HEI_ASSERT(iv_children.end() == iv_children.find(i_bit));

    // The child register should not be null.
    HEI_ASSERT(nullptr != i_child);

    // Add the new rule.
    iv_children[i_bit] = 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
