#pragma once

#include <libpldm/bios_table.h>

#include <cstring>
#include <memory>
#include <type_traits>
#include <vector>

namespace pldm
{
namespace bios
{
namespace utils
{

using Table = std::vector<uint8_t>;

/** @class BIOSTableIter
 *  @brief Const Iterator of a BIOS Table
 */
template <pldm_bios_table_types tableType>
class BIOSTableIter
{
  public:
    /** @struct EndSentinel
     *  @brief Auxiliary struct to delimit a range
     */
    struct EndSentinel
    {};

    /** @struct iterator
     *  @brief iterator owns the BIOS table
     */
    class iterator
    {
      public:
        /** @brief Get entry type by specifying \p tableType
         */
        using T = typename std::conditional<
            tableType == PLDM_BIOS_STRING_TABLE, pldm_bios_string_table_entry,
            typename std::conditional<
                tableType == PLDM_BIOS_ATTR_TABLE, pldm_bios_attr_table_entry,
                typename std::conditional<tableType == PLDM_BIOS_ATTR_VAL_TABLE,
                                          pldm_bios_attr_val_table_entry,
                                          void>::type>::type>::type;
        static_assert(!std::is_void<T>::value);

        /** @brief Constructors iterator
         *
         *  @param[in] data - Pointer to a table
         *  @param[in] length - The length of the table
         */
        explicit iterator(const void* data, size_t length) :
            iter(pldm_bios_table_iter_create(data, length, tableType),
                 pldm_bios_table_iter_free)
        {
            if (!iter)
            {
                throw std::runtime_error(
                    "Unable to create bios table iterator");
            }
        }

        /** @brief Get the entry pointed by the iterator
         *
         *  @return Poiner to the entry
         */
        const T* operator*() const
        {
            return reinterpret_cast<const T*>(
                pldm_bios_table_iter_value(iter.get()));
        }

        /** @brief Make the iterator point to the next entry
         *
         *  @return The iterator itself
         */
        iterator& operator++()
        {
            pldm_bios_table_iter_next(iter.get());
            return *this;
        }

        /** @brief Check if the iterator ends
         *
         *  @return True if the iterator ends
         */
        bool operator==(const EndSentinel&) const
        {
            return pldm_bios_table_iter_is_end(iter.get());
        }

        /** @brief Check if the iterator ends
         *
         *  @return False if the iterator ends
         */
        bool operator!=(const EndSentinel& endSentinel) const
        {
            return !operator==(endSentinel);
        }

      private:
        std::unique_ptr<pldm_bios_table_iter,
                        decltype(&pldm_bios_table_iter_free)>
            iter;
    };

    /** @brief Constructors BIOSTableIterator
     *
     *  @param[in] data - Pointer to a table
     *  @param[in] length - The length of the table
     */
    BIOSTableIter(const void* data, size_t length) noexcept :
        tableData(data), tableSize(length)
    {}

    /** @brief Get the iterator to the beginning
     *
     *  @return An iterator to the beginning
     */
    iterator begin()
    {
        return iterator(tableData, tableSize);
    }

    /** @brief Get the iterator to the end
     *
     *  @return An iterator to the end
     */
    EndSentinel end()
    {
        return {};
    }

  private:
    const void* tableData;
    size_t tableSize;
};

} // namespace utils
} // namespace bios
} // namespace pldm
