#pragma once

#include <register/hei_hardware_register.hpp>
#include <util/hei_flyweight.hpp>

namespace libhei
{

/**
 * @brief A Power Systems SCOM register.
 *
 * Address width:   4 bytes
 * Register width:  8 bytes
 * Bit order:       Ascending (0-63 left to right)
 */
class ScomRegister : public HardwareRegister
{
  public: // Constructor, destructors, assignment, etc.

    /**
     * @brief Constructor from components.
     * @param i_chipType    Type of chip associated with this register.
     * @param i_id          Unique ID for this register.
     * @param i_instance    Instance of this register
     * @param i_accessLevel Hardware access level for this register.
     * @param i_address     A 4-byte address for this SCOM register.
     */
    ScomRegister(ChipType_t i_chipType, RegisterId_t i_id,
                 RegisterInstance_t i_instance,
                 RegisterAccessLevel_t i_accessLevel, uint32_t i_address) :
        HardwareRegister(i_chipType, i_id, i_instance, i_accessLevel),
        iv_address(i_address)
    {}

    /** @brief Destructor. */
    ~ScomRegister() = 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<ScomRegister>;

    /**
     * @brief Copy constructor.
     *
     * Needed by Flyweight class, but should not be allowed in general.
     */
    ScomRegister(const ScomRegister&) = 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.
     */
    ScomRegister& operator=(const ScomRegister&) = delete;

  public: // Accessor functions

    /** Function overloaded from parent HardwareRegister class. */
    RegisterType_t getRegisterType() const
    {
        return REG_TYPE_SCOM;
    }

    /** Function overloaded from parent HardwareRegister class. */
    RegisterAddress_t getAddress() const
    {
        return static_cast<RegisterAddress_t>(iv_address);
    }

    /** Function overloaded from parent HardwareRegister class. */
    size_t getSize() const
    {
        return 8;
    }

  private: // Instance variables

    /** This register's address. */
    const uint32_t iv_address;

}; // end class ScomRegister

/**
 * @brief A Power Systems Indirect SCOM register.
 *
 * Address width:   8 bytes
 * Register width:  2* bytes (see note below)
 * Bit order:       Ascending (0-63 left to right)
 *
 * IMPORTANT NOTE:
 *   Technically, only two bytes of data are actually used. However, the bit
 *   definition of these registers put the two bytes at the end of the returned
 *   value (bit 48-63). Therefore, this class will be made to look like the
 *   width is 8 bytes in order to make the bit indexing work in the returned
 *   BitString.
 */
class IdScomRegister : public HardwareRegister
{
  public: // Constructor, destructors, assignment, etc.

    /**
     * @brief Constructor from components.
     * @param i_chipType    Type of chip associated with this register.
     * @param i_id          Unique ID for this register.
     * @param i_instance    Instance of this register
     * @param i_accessLevel Hardware access level for this register.
     * @param i_address     An 8-byte address for this Indirect SCOM register.
     */
    IdScomRegister(ChipType_t i_chipType, RegisterId_t i_id,
                   RegisterInstance_t i_instance,
                   RegisterAccessLevel_t i_accessLevel, uint64_t i_address) :
        HardwareRegister(i_chipType, i_id, i_instance, i_accessLevel),
        iv_address(i_address)
    {}

    /** @brief Destructor. */
    ~IdScomRegister() = 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<IdScomRegister>;

    /**
     * @brief Copy constructor.
     *
     * Needed by Flyweight class, but should not be allowed in general.
     */
    IdScomRegister(const IdScomRegister&) = 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.
     */
    IdScomRegister& operator=(const IdScomRegister&) = delete;

  public: // Accessor functions

    /** Function overloaded from parent HardwareRegister class. */
    RegisterType_t getRegisterType() const
    {
        return REG_TYPE_ID_SCOM;
    }

    /** Function overloaded from parent HardwareRegister class. */
    RegisterAddress_t getAddress() const
    {
        return static_cast<RegisterAddress_t>(iv_address);
    }

    /** Function overloaded from parent HardwareRegister class. */
    size_t getSize() const
    {
        return 8; // See note in class documentation.
    }

  private: // Instance variables

    /** This register's address. */
    const uint64_t iv_address;

}; // end class IdScomRegister

} // end namespace libhei
