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

extern "C" {
#include "backend.h"
#include "vpnor/backend.h"
};

#include "vpnor/table.hpp"

#include <fcntl.h>
#include <unistd.h>

#include <experimental/filesystem>
#include <string>

namespace openpower
{
namespace virtual_pnor
{

namespace fs = std::experimental::filesystem;

class Request
{
  public:
    /** @brief Construct a flash access request
     *
     *  @param[in] backend - The backend context used to process the request
     *  @param[in] offset - The absolute offset into the flash device as
     *                      provided by the mbox message associated with the
     *                      request
     *
     *  The class does not take ownership of the ctx pointer. The lifetime of
     *  the ctx pointer must strictly exceed the lifetime of the class
     *  instance.
     */
    Request(struct backend* backend, size_t offset) :
        backend(backend), partition(((struct vpnor_data*)backend->priv)
                                        ->vpnor->table->partition(offset)),
        base(partition.data.base << backend->block_size_shift),
        offset(offset - base)
    {
    }
    Request(const Request&) = delete;
    Request& operator=(const Request&) = delete;
    Request(Request&&) = default;
    Request& operator=(Request&&) = default;
    ~Request() = default;

    ssize_t read(void* dst, size_t len)
    {
        len = clamp(len);
        constexpr auto flags = O_RDONLY;
        fs::path path = getPartitionFilePath(flags);
        return fulfil(path, flags, dst, len);
    }

    ssize_t write(void* dst, size_t len)
    {
        if (len != clamp(len))
        {
            std::stringstream err;
            err << "Request size 0x" << std::hex << len << " from offset 0x"
                << std::hex << offset << " exceeds the partition size 0x"
                << std::hex
                << (partition.data.size << backend->block_size_shift);
            throw OutOfBoundsOffset(err.str());
        }
        constexpr auto flags = O_RDWR;
        /* Ensure file is at least the size of the maximum access */
        fs::path path = getPartitionFilePath(flags);
        resize(path, len);
        return fulfil(path, flags, dst, len);
    }

  private:
    /** @brief Clamp the access length to the maximum supported by the ToC */
    size_t clamp(size_t len);

    /** @brief Ensure the backing file is sized appropriately for the access
     *
     *  We need to ensure the file is big enough to satisfy the request so that
     *  mmap() will succeed for the required size.
     *
     *  @return The valid access length
     *
     *  Throws: std::system_error
     */
    void resize(const std::experimental::filesystem::path& path, size_t len);

    /** @brief Returns the partition file path associated with the offset.
     *
     *  The search strategy for the partition file depends on the value of the
     *  flags parameter.
     *
     *  For the O_RDONLY case:
     *
     *  1.  Depending on the partition type,tries to open the file
     *      from the associated partition(RW/PRSV/RO).
     *  1a. if file not found in the corresponding
     *      partition(RW/PRSV/RO) then tries to read the file from
     *      the read only partition.
     *  1b. if the file not found in the read only partition then
     *      throw exception.
     *
     * For the O_RDWR case:
     *
     *  1.  Depending on the partition type tries to open the file
     *      from the associated partition.
     *  1a. if file not found in the corresponding partition(RW/PRSV)
     *      then copy the file from the read only partition to the (RW/PRSV)
     *      partition depending on the partition type.
     *  1b. if the file not found in the read only partition then throw
     *      exception.
     *
     *  @param[in] flags - The flags that will be used to open the file. Must
     *                     be one of O_RDONLY or O_RDWR.
     *
     *  Post-condition: The file described by the returned path exists
     *
     *  Throws: std::filesystem_error, std::bad_alloc
     */
    std::experimental::filesystem::path getPartitionFilePath(int flags);

    /** @brief Fill dst with the content of the partition relative to offset.
     *
     *  @param[in] offset - The pnor offset(bytes).
     *  @param[out] dst - The buffer to fill with partition data
     *  @param[in] len - The length of the destination buffer
     */
    size_t fulfil(const std::experimental::filesystem::path& path, int flags,
                  void* dst, size_t len);

    struct backend* backend;
    const pnor_partition& partition;
    size_t base;
    size_t offset;
};

} // namespace virtual_pnor
} // namespace openpower
