#pragma once

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

#include "libpldm/bios_table.h"

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) noexcept :
            iter(pldm_bios_table_iter_create(data, length, tableType),
                 pldm_bios_table_iter_free)
        {
        }

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