#pragma once

#include <hei_includes.hpp>
#include <register/hei_register.hpp>
#include <util/hei_bit_string.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;

    /** @return The size (in bytes) of this register. */
    virtual size_t getSize() 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;

    /**
     * @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

  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
