#pragma once

#include <hei_includes.hpp>
#include <hei_isolation_data.hpp>
#include <register/hei_register.hpp>
#include <register/hei_hardware_register.hpp>
#include <util/hei_bit_string.hpp>
#include <util/hei_flyweight.hpp>

namespace libhei
{

/**
 * @brief This class contains the isolation rules and bit definition of a
 *        HardwareRegister used for error isolation.
 *
 * These objects are linked together as a tree. Any active bits in the
 * associated register will either be a true active attention (leaf node) or
 * indicate one or more active attentions occurred in a child node.
 *
 * The primary function of this class is analyze(), which will do a depth-first
 * search of the tree to find all leaves and add their signatures to the
 * returned isolation data.
 *
 * The tree structure is built from information in the Chip Data Files. It is
 * possible that the tree could be built with loop in the isolation. This would
 * be bug in the Chip Data Files. This class will keep track of all nodes that
 * have been analyzed to prevent cyclic isolation (an infinite loop).
 *
 * Each isolation register will have a rule for each supported attention type.
 * These rules are a combination of HardwareRegisters and operator registers to
 * define rules like "REG & ~MASK & CNFG", which reads "return all bits in REG
 * that are not in MASK and set in CNFG". See the definition of the Register
 * class for details on how this works.
 */
class IsolationNode
{
  public: // Constructors, destructor, assignment

    /**
     * @brief Constructor from components.
     * @param i_hwReg A reference to the HardwareRegister targeted for
     *                isolation.
     */
    explicit IsolationNode(const HardwareRegister & i_hwReg) :
        iv_hwReg(i_hwReg)
    {}

    /** @brief Destructor. */
    ~IsolationNode() = default;

  private:

    // This is needed to allow the flyweights to use the copy constructor, but
    // not allow it to be used in general.
    friend class Flyweight<IsolationNode>;

    /**
     * @brief Copy constructor.
     *
     * Needed by Flyweight class, but should not be allowed in general.
     */
    IsolationNode(const IsolationNode &) = default;

    /**
     * @brief Explicitly disables assignment operator.
     *
     * This is redundant since the compilier will implicitly delete this because
     * of the constant instance variables, but helps communicate it is not
     * allowed.
     */
    IsolationNode & operator=(const IsolationNode &) = delete;

  private: // Instance variables

    /**
     * This is a reference to the HardwareRegister targeted for isolation by
     * this instance of the class. The reference is required to maintain
     * polymorphism.
     */
    const HardwareRegister & iv_hwReg;

    /**
     * This register could report multiple types of attentions. We can use a
     * register 'rule' (value) to find any active attentions for each attention
     * type (key). A 'rule', like "register & ~mask", is a combination of
     * HardwareRegister objects and virtual operator registers (all children
     * of the Register class).
     */
    std::map<AttentionType_t, const Register *> iv_rules;

    /**
     * Each bit (key) in this map indicates that an attention was driven from
     * another register (value).
     */
    std::map<RegisterBit_t, const IsolationNode *> iv_children;

  public: // Member functions

    /**
     * @brief  Finds all active attentions on this register. If an active bit is
     *         a leaf in the isolation tree, the bit's signature is added to the
     *         isolation data. Otherwise, this function is recursively called
     *         to analyze the child register that is driving the attention in
     *         this register.
     * @param  i_chip     The target chip for isolation.
     * @param  i_attnType The target attention type to analyze on this register.
     *                    Will assert a rule must exist for this attention type.
     * @param  io_isoData The isolation data returned back to the user
     *                    application.
     * @return True, if any active attentions found on this register.
     *         False, otherwise.
     */
    bool analyze(const Chip & i_chip, AttentionType_t i_attnType,
                 IsolationData & io_isoData) const;

    // TODO: The next two functions are only intended to be used during
    //       initialization of the isolator. Consider, making them private and
    //       make the Chip Data File code friends of this class. So that it has
    //       access to these init functions.

    /**
     * @brief Adds a register rule for the given attention type. See iv_rules
     *        for details.
     *
     * This is only intended to be used during initialization of the isolator.
     * Will assert that nothing has already been defined for this rule.
     *
     * @param The target attention type.
     * @param The rule for this attention type.
     */
    void addRule(AttentionType_t i_attnType, const Register * i_rule);

    /**
     * @brief Adds a child register to analyze for the given bit in this
     *        register. See iv_children for details.
     *
     * This is only intended to be used during initialization of the isolator.
     * Will assert that nothing has already been defined for this bit.
     *
     * @param The target bit on this register.
     * @param The child register to analyze for the given bit.
     */
    void addChild(RegisterBit_t i_bit, const IsolationNode * i_child);

  public: // Operators

    /** @brief Equals operator. */
    bool operator==(const IsolationNode & i_r) const
    {
        // iv_hwReg should be unique per IsolationNode.
        return (iv_hwReg == i_r.iv_hwReg);
    }

    /** @brief Less than operator. */
    bool operator<(const IsolationNode & i_r) const
    {
        // iv_hwReg should be unique per IsolationNode.
        return (iv_hwReg < i_r.iv_hwReg);
    }

  private: // Isolation stack and supporting functions.

    /** When analyze() is called at the tree root, all recursive calls to
     *  analyze() will target the same chip and attention type. So we only need
     *  to keep track of the nodes that have been analyzed to avoid cyclic
     *  isolation (an infinite loop). In fact, we only need to keep track of the
     *  nodes directly from this node to the root node. As long as this node
     *  does not already exist in the list, we can be sure there will not be a
     *  loop. So the list can be treated as a stack. When analyze() is called on
     *  a node, that node is pushed to the top of the stack (as long as it
     *  doesn't already exist in the stack). Then, just before analyze() exits,
     *  this node can be popped off the top of the stack. Once all the recursive
     *  calls have returned back to the root node the stack should be empty.
     */
    static std::vector<const IsolationNode *> cv_isolationStack;

    /**
     * @brief Pushes this node to the top of the stack. Will assert that this
     *        node does not already exist in cv_isolationStack.
     */
    void pushIsolationStack() const;

    /** @brief Pops the top node off of cv_isolationStack. */
    void popIsolationStack() const { cv_isolationStack.pop_back(); }

};

} // end namespace libhei
