#pragma once

#include <vector>
#include <memory>
#include <numeric>
#include <experimental/filesystem>
#include "pnor_partition_defs.h"

namespace openpower
{
namespace virtual_pnor
{

namespace fs = std::experimental::filesystem;

using PartitionTable = std::vector<uint8_t>;
using checksum_t = uint32_t;

/** @brief Convert the input partition table to big endian.
 *
 *  @param[in] src - reference to the pnor partition table
 *
 *  @returns converted partition table
 */
PartitionTable endianFixup(const PartitionTable& src);

namespace details
{

/** @brief Compute XOR-based checksum, by XORing consecutive words
 *         in the input data. Input must be aligned to word boundary.
 *
 *  @param[in] data - input data on which checksum is computed
 *
 *  @returns computed checksum
 */
template <class T>
checksum_t checksum(const T& data)
{
    static_assert(sizeof(decltype(data)) % sizeof(checksum_t) == 0,
                  "sizeof(data) is not aligned to sizeof(checksum_t) boundary");

    auto begin = reinterpret_cast<const checksum_t*>(&data);
    auto end = begin + (sizeof(decltype(data)) / sizeof(checksum_t));

    return std::accumulate(begin, end, 0, std::bit_xor<checksum_t>());
}

} // namespace details

namespace partition
{

/** @class Table
 *  @brief Generates virtual PNOR partition table.
 *
 *  Generates virtual PNOR partition table upon construction. Reads
 *  the PNOR information generated by this tool :
 *  github.com/openbmc/openpower-pnor-code-mgmt/blob/master/generate-squashfs,
 *  which generates a minimalistic table-of-contents (toc) file and
 *  individual files to represent various partitions that are of interest -
 *  these help form the "virtual" PNOR, which is typically a subset of the full
 *  PNOR image.
 *  These files are stored in a well-known location on the PNOR.
 *  Based on this information, this class prepares the partition table whose
 *  structure is as outlined in pnor_partition.h.
 *
 *  The virtual PNOR supports 4KB erase blocks - partitions must be aligned to
 *  this size.
 */
class Table
{
    public:
        /** @brief Constructor accepting the path of the directory
         *         that houses the PNOR partition files.
         *
         *  @param[in] directory - path of the directory housing PNOR partitions
         */
        Table(fs::path&& directory);

        Table();
        Table(const Table&) = delete;
        Table& operator=(const Table&) = delete;
        Table(Table&&) = delete;
        Table& operator=(Table&&) = delete;
        ~Table() = default;

        /** @brief Return size of partition table
         *
         *  @returns size_t - size of partition table in blocks
         */
        size_t size() const
        {
            return szBlocks;
        }

        /** @brief Return a partition table having byte-ordering
         *         that the host expects.
         *
         *  The host needs the partion table in big-endian.
         *
         *  @returns const reference to host partition table.
         */
        const pnor_partition_table& getHostTable() const
        {
            return *(reinterpret_cast<
                         const pnor_partition_table*>(hostTbl.data()));
        }

        /** @brief Return a little-endian partition table
         *
         *  @returns const reference to native partition table
         */
        const pnor_partition_table& getNativeTable() const
        {
            return *(reinterpret_cast<const pnor_partition_table*>(tbl.data()));
        }

        /** @brief Return partition corresponding to PNOR offset, the offset
         *         is within returned partition.
         *
         *  @param[in] offset - PNOR offset in bytes
         *
         *  @returns const reference to pnor_partition, if found, else a
         *           reference to a zeroed out pnor_partition structure.
         */
        const pnor_partition& partition(size_t offset) const;

    private:
        /** @brief Prepares a vector of PNOR partition structures.
         */
        void preparePartitions();

        /** @brief Prepares the PNOR header.
         */
        void prepareHeader();

        /** @brief Allocate memory to hold the partion table. Determine the
         *         amount needed based on the partition files in the toc file.
         *
         *  @param[in] tocFile - Table of contents file path.
         */
        void allocateMemory(const fs::path& tocFile);

        /** @brief Populate fields related to sizes for the input
         *         pnor_partition structure.
         *
         *  @param[in/out] part - pnor_partition structure
         *  @param[in] start - partition start address
         *  @param[in] end - partition end address
         */
        void writeSizes(pnor_partition& part, size_t start, size_t end);

        /** @brief Populate userdata bits for the input
         *         pnor_partition structure.
         *
         *  @param[in/out] part - pnor_partition structure
         *  @param[in] data - string having userdata fields in a
         *             comma-separated line.
         */
        void writeUserdata(pnor_partition& part, const std::string& data);

        /** @brief Populate the name and id fields for the input
         *         pnor_partition structure.
         *
         *  @param[in/out] part - pnor_partition structure
         *  @param[in] name - partition name
         *  @param[id] id - partition id
         */
        void writeNameAndId(pnor_partition& part, std::string&& name,
                            const std::string& id);

        /** @brief Populate default/unused fields for the input
         *         pnor_partition structure.
         *
         *  @param[in/out] part - pnor_partition structure
         */
        void writeDefaults(pnor_partition& part);

        /** @brief Return a little-endian partition table
         *
         *  @returns reference to native partition table
         */
        pnor_partition_table& getNativeTable()
        {
            return *(reinterpret_cast<pnor_partition_table*>(tbl.data()));
        }

        /** @brief Size of the PNOR partition table -
         *         sizeof(pnor_partition_table) +
         *         (no. of partitions * sizeof(pnor_partition)),
         *         measured in erase-blocks.
         */
        size_t szBlocks;

        /** @brief Size of virtual PNOR image, measured in erase-blocks */
        size_t imgBlocks;

        /** @brief Partition table */
        PartitionTable tbl;

        /** @brief Partition table with host byte ordering */
        PartitionTable hostTbl;

        /** @brief Directory housing generated PNOR partition files */
        fs::path directory;

        /** @brief Number of partitions */
        size_t numParts;
};

} // namespace partition
} // namespace virtual_pnor
} // namespace openpower
