#pragma once

#include <hei_includes.hpp>
#include <hei_isolation_data.hpp>
#include <register/hei_hardware_register.hpp>
#include <register/hei_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();
    }
};

/** Pointer management for isolation nodes. */
using IsolationNodePtr = std::shared_ptr<IsolationNode>;

/** Simple map to ensure only one root IsolationNode per attention type. */
using RootNodeMap = std::map<AttentionType_t, const IsolationNodePtr>;

} // end namespace libhei
