#pragma once

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

namespace libhei
{

/**
 * @brief An abstract class containing information (e.g. address, type, length,
 *        etc.) for an actual hardware register.
 *
 * Hardware access:
 *
 *  Actual hardware access is defined by the user application via the user
 *  interface APIs. In order to tell the user application which chip to target,
 *  the user application will give the isolator a list of pointers to its
 *  objects. They will then be passed into the public functions of this class
 *  and eventually given back to the user application when hardware access is
 *  needed.
 *
 * Register cache:
 *
 *  In order to save memory space, each instance of this class does not store
 *  the contents of the target hardware register. Instead, that data is stored
 *  in a register cache, which is a static variable defined in this class. This
 *  allows us to store only what we need. The cache can also be thought of as a
 *  snapshot of the registers at the time of isolation, which can be useful if
 *  the hardware is still running and register values could change.
 *
 *  In order to ensure stale data isn't used from the cache, call
 *  HardwareRegister::flushAll() before beginning isolation on a new attention.
 *  Also, HardwareRegister::flushAll() should be called when the isolator is
 *  uninitialized before the rest of the isolation objects are deleted.
 */
class HardwareRegister : public Register
{
  public: // Aliases
    using Ptr = std::shared_ptr<HardwareRegister>;
    using ConstPtr = std::shared_ptr<const HardwareRegister>;

    using Key = std::pair<RegisterId_t, Instance_t>;

  public:
    /** @brief Pure virtual destructor. */
    virtual ~HardwareRegister() = 0;

  protected:
    /**
     * @brief Constructor from components.
     * @param i_id       Unique ID for this register.
     * @param i_instance Instance of this register
     * @param i_flags    Attribute flags for this register.
     */
    HardwareRegister(RegisterId_t i_id, Instance_t i_instance,
                     RegisterAttributeFlags_t i_flags) :
        Register(), iv_id(i_id), iv_instance(i_instance), iv_flags(i_flags)
    {}

  private: // Instance variables
    /** The unique ID for this register. */
    const RegisterId_t iv_id;

    /** A register may have multiple instances. All of which will have the same
     *  ID. This variable is used to distinguish between each instance of the
     *  register. */
    const Instance_t iv_instance;

    /** The hardware access level of this register (read/write, read-only,
     *  write-only, etc.). */
    const RegisterAttributeFlags_t iv_flags;

  public: // Accessor functions
    /* @return The unique ID for this register. */
    RegisterId_t getId() const
    {
        return iv_id;
    }

    /* @return The instance of this register. */
    Instance_t getInstance() const
    {
        return iv_instance;
    }

    /** @return The register/instance key. */
    Key getKey() const
    {
        return {iv_id, iv_instance};
    }

    /** @return True if given flag is enabled, false if disabled. */
    bool queryAttrFlag(RegisterAttributeFlags_t i_flag) const
    {
        return (0 != (iv_flags & i_flag));
    }

    // NOTE: The following are determined by child classes.

    /** @return This register's type. */
    virtual RegisterType_t getType() const = 0;

    /** @return The address of this register. */
    virtual RegisterAddress_t getAddress() const = 0;

  public: // Operators
    /** @brief Equals operator. */
    bool operator==(const HardwareRegister& i_r) const
    {
        // In general, comparing the ID and instance should be enough. However,
        // no error will be thrown when adding the register to the flyweights
        // and any other field differs. Therefore, all fields will be used and
        // invalid duplicates will be found when adding the register pointers
        // to the IsolationChip objects.
        return (getAddress() == i_r.getAddress()) && (getId() == i_r.getId()) &&
               (getInstance() == i_r.getInstance()) &&
               (getType() == i_r.getType()) && (iv_flags == i_r.iv_flags);
    }

    /** @brief Less than operator. */
    bool operator<(const HardwareRegister& i_r) const
    {
        // In general, comparing the ID and instance should be enough. However,
        // no error will be thrown when adding the register to the flyweights
        // and any other field differs. Therefore, all fields will be used and
        // invalid duplicates will be found when adding the register pointers
        // to the IsolationChip objects.
        if (getAddress() < i_r.getAddress())
        {
            return true;
        }
        else if (getAddress() == i_r.getAddress())
        {
            if (getId() < i_r.getId())
            {
                return true;
            }
            else if (getId() == i_r.getId())
            {
                if (getInstance() < i_r.getInstance())
                {
                    return true;
                }
                else if (getInstance() == i_r.getInstance())
                {
                    if (getType() < i_r.getType())
                    {
                        return true;
                    }
                    else if (getType() == i_r.getType())
                    {
                        return (iv_flags < i_r.iv_flags);
                    }
                }
            }
        }

        return false;
    }

  public:
    /** Function overloaded from parent Register class. */
    const BitString* getBitString(const Chip& i_chip) const override;

    /**
     * @brief  Reads a register from hardware via the user interface APIs.
     * @param  i_chip  The target chip in which this register belongs.
     * @param  i_force When false, this function will only read from hardware if
     *                 an entry for this instance does not already exist in the
     *                 register cache. When true, the entry in the register
     *                 cache is flushed, if it exists. Then this function will
     *                 read from hardware and update the cache.
     * @return See the return code from the registerRead() user interface API.
     */
    bool read(const Chip& i_chip, bool i_force = false) const;

#ifdef __HEI_ENABLE_HW_WRITE

    /**
     * @brief  Writes the value stored in the register cache to hardware via the
     *         user interface APIs.
     * @param  i_chip  The target chip in which this register belongs.
     * @return See the return code from the registerWrite() user interface API.
     */
    bool write(const Chip& i_chip) const;

#endif // __HEI_ENABLE_HW_WRITE

    /**
     * @brief Sets the target position to 1 in the cached bit string.
     * @param i_chip The target chip in which this register belongs.
     * @param i_pos  The target position.
     */
    void setBit(const Chip& i_chip, uint64_t i_pos) const;

    /**
     * @brief Sets the entire cached bit string to 1s.
     * @param i_chip The target chip in which this register belongs.
     */
    void setAllBits(const Chip& i_chip) const;

    /**
     * @brief Sets the target position to 0 in the cached bit string.
     * @param i_chip The target chip in which this register belongs.
     * @param i_pos  The target position.
     */
    void clearBit(const Chip& i_chip, uint64_t i_pos) const;

    /**
     * @brief Sets the entire cached bit string to 0s.
     * @param i_chip The target chip in which this register belongs.
     */
    void clearAllBits(const Chip& i_chip) const;

  protected:
    /**
     * @brief  Provides access to this register's BitString.
     *
     * WARNING: Allowing public access to this function may be dangerous. For
     *          now it should be left as protected.
     *
     * @param  i_chip  The target chip in which this register belongs.
     * @return A reference to the BitString.
     */
    BitString& accessBitString(const Chip& i_chip);

  private: // Register cache class variable
    /**
     * @brief Caches the contents of registers read from hardware.
     *
     * The goal is to create a snapshot of the hardware register contents as
     * close to the reported attention as possible. This snapshot is then used
     * for additional analysis/debug when needed.
     */
    class Cache
    {
      public:
        /** @brief Default constructor. */
        Cache() = default;

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

        /** @brief Copy constructor. */
        Cache(const Cache&) = delete;

        /** @brief Assignment operator. */
        Cache& operator=(const Cache&) = delete;

        /**
         * @brief  Queries if a specific entry exists in the cache.
         * @param  i_chip  The target chip.
         * @param  i_hwReg The target register.
         * @return True if the entry exists, false otherwise.
         */
        bool query(const Chip& i_chip, const HardwareRegister* i_hwReg) const;

        /**
         * @brief  Returns the data buffer for the given chip and register.
         * @param  i_chip  The target chip.
         * @param  i_hwReg The target register.
         * @return A reference to the BitString containing the register data.
         * @note   If an entry does not exist in the cache, an entry will be
         *         created and the BitString will be initialized to 0.
         */
        BitString& access(const Chip& i_chip, const HardwareRegister* i_hwReg);

        /** @brief Flushes entire contents from cache. */
        void flush();

        /**
         * @brief Removes a single register from the cache.
         * @param i_chip  The target chip.
         * @param i_hwReg The target register.
         */
        void flush(const Chip& i_chip, const HardwareRegister* i_hwReg);

      private:
        /**
         * @brief Stores a BitStringBuffer for each HardwareRegister per Chip.
         *
         * The HardwareRegister keys will just be pointers to the isolation
         * objects created in the main initialize() API. Those should exist
         * until the main uninitialize() API is called. It is important that the
         * cache is flushed at the beginning of the uninitialize() API before
         * the rest of the isolation objects are deleted.
         *
         * The Chip keys are copies of the objects passed to the isolator
         * because the user application is responsible for storage of the
         * objects passed to the isolator. We don't want to chance a Chip was
         * created as a local variable that goes out of scope, or other similar
         * situations.
         */
        std::map<Chip, std::map<const HardwareRegister*, BitString*>> iv_cache;
    };

    /** This allows all HardwareRegister objects access to the cache. */
    static Cache cv_cache;

  public: // Register cache management functions.
    /** @brief Flushes the entire register cache. */
    static void flushAll()
    {
        cv_cache.flush();
    }

    /**
     * @brief Flushes this register from the cache.
     * @param  i_chip  The target chip in which this register belongs.
     */
    void flush(const Chip& i_chip) const
    {
        cv_cache.flush(i_chip, this);
    }

  private: // Register cache management functions.
    /**
     * @param  i_chip  The target chip in which this register belongs.
     * @return True if an entry for this register exist in this cache.
     */
    bool queryCache(const Chip& i_chip) const
    {
        return cv_cache.query(i_chip, this);
    }

    /**
     * @param  i_chip  The target chip in which this register belongs.
     * @return A reference to this register's BitString in cache.
     */
    BitString& accessCache(const Chip& i_chip) const
    {
        return cv_cache.access(i_chip, this);
    }
};

} // end namespace libhei
