/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright (C) 2018 IBM Corp. */
#pragma once

#include <vector>
#include <memory>
#include <numeric>
#include <experimental/filesystem>
#include "common.h"
#include "mbox.h"
#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);

/** @brief Parse a ToC line (entry) into the corresponding FFS partition
 * object.
 *
 * @param[in] line - The ToC line to parse
 * @param[in] blockSize - The flash block size in bytes
 * @param[out] part - The partition object to populate with the information
 *                    parsed from the provided ToC line
 *
 * Throws: MalformedTocEntry, InvalidTocEntry
 */
void parseTocLine(const std::string& line, size_t blockSize,
                  pnor_partition& part);

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] ctx - Acquire sizes and paths relevant to the table
     *
     * Throws MalformedTocEntry, InvalidTocEntry
     */
    Table(const struct mbox_context* ctx);

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

    /** @brief Return the exact size of partition table in bytes
     *
     *  @returns size_t - size of partition table in bytes
     */
    size_t size() const
    {
        return szBytes;
    }

    /** @brief Return aligned size of partition table in bytes
     *
     *  The value returned will be greater-than or equal to size(), and
     *  aligned to blockSize.
     *
     *  @returns size_t - capacity of partition table in bytes
     */
    size_t capacity() const
    {
        return align_up(szBytes, blockSize);
    }

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

    /** @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 an
     *           exception will be thrown.
     *
     *  Throws: UnmappedOffset
     */
    const pnor_partition& partition(size_t offset) const;

    /** @brief Return partition corresponding to input partition name.
     *
     *  @param[in] name - PNOR partition name
     *
     *  @returns const reference to pnor_partition, if found, else an
     *           exception will be thrown.
     *
     *  Throws: UnknownPartition
     */
    const pnor_partition& partition(const std::string& name) const;

  private:
    /** @brief Prepares a vector of PNOR partition structures.
     *
     *  @param[in] ctx - An mbox context providing partition locations
     *
     * Throws: MalformedTocEntry, InvalidTocEntry
     */
    void preparePartitions(const struct mbox_context* ctx);

    /** @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 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)),
     */
    size_t szBytes;

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

    /** @brief PNOR block size, in bytes */
    size_t blockSize;

    /** @brief PNOR size, in bytes */
    size_t pnorSize;
};
} // namespace partition

/** @brief An exception type storing a reason string.
 *
 *  This looks a lot like how std::runtime_error might be implemented however
 *  we want to avoid extending it, as exceptions extending ReasonedError have
 *  an expectation of being handled (can be predicted and are inside the scope
 *  of the program).
 *
 *  From std::runtime_error documentation[1]:
 *
 *  > Defines a type of object to be thrown as exception. It reports errors
 *  > that are due to events beyond the scope of the program and can not be
 *  > easily predicted.
 *
 *  [1] http://en.cppreference.com/w/cpp/error/runtime_error
 *
 *  We need to keep the inheritance hierarchy separate: This avoids the
 *  introduction of code that overzealously catches std::runtime_error to
 *  handle exceptions that would otherwise derive ReasonedError, and in the
 *  process swallows genuine runtime failures.
 */
class ReasonedError : public std::exception
{
  public:
    ReasonedError(const std::string&& what) : _what(what)
    {
    }
    const char* what() const noexcept
    {
        return _what.c_str();
    };

  private:
    const std::string _what;
};

/** @brief Base exception type for errors related to ToC entry parsing.
 *
 *  Callers of parseTocEntry() may not be concerned with the specifics and
 *  rather just want to extract and log what().
 */
class TocEntryError : public ReasonedError
{
  public:
    TocEntryError(const std::string&& reason) : ReasonedError(std::move(reason))
    {
    }
};

/** @brief The exception thrown on finding a syntax error in the ToC entry
 *
 *  If the syntax is wrong, or expected values are missing, the ToC entry is
 *  malformed
 */
class MalformedTocEntry : public TocEntryError
{
  public:
    MalformedTocEntry(const std::string&& reason) :
        TocEntryError(std::move(reason))
    {
    }
};

/** @brief The exception thrown on finding a semantic error in the ToC entry
 *
 *  If the syntax of the ToC entry is correct but the semantics are broken,
 *  then we have an invalid ToC entry.
 */
class InvalidTocEntry : public TocEntryError
{
  public:
    InvalidTocEntry(const std::string&& reason) :
        TocEntryError(std::move(reason))
    {
    }
};

class UnmappedOffset : public std::exception
{
  public:
    UnmappedOffset(size_t base, size_t next) : base(base), next(next)
    {
    }

    const size_t base;
    const size_t next;
};

class OutOfBoundsOffset : public ReasonedError
{
  public:
    OutOfBoundsOffset(const std::string&& reason) :
        ReasonedError(std::move(reason))
    {
    }
};

class UnknownPartition : public ReasonedError
{
  public:
    UnknownPartition(const std::string&& reason) :
        ReasonedError(std::move(reason))
    {
    }
};

} // namespace virtual_pnor
} // namespace openpower

struct vpnor_partition_table
{
    openpower::virtual_pnor::partition::Table* table;
};
