// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
extern "C" {
#include "mboxd.h"
}

#include "config.h"

#include "vpnor/partition.hpp"
#include "vpnor/table.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>

#include <exception>
#include <iostream>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <stdexcept>
#include <string>

#include "common.h"
#include "vpnor/backend.h"

namespace openpower
{
namespace virtual_pnor
{

namespace fs = std::filesystem;

fs::path Request::getPartitionFilePath(int flags)
{
    struct vpnor_data* priv = (struct vpnor_data*)backend->priv;

    // Check if partition exists in patch location
    auto dst = fs::path(priv->paths.patch_loc) / partition.data.name;
    if (fs::is_regular_file(dst))
    {
        return dst;
    }

    // Check if partition exists in rw location (default)
    dst = fs::path(priv->paths.rw_loc) / partition.data.name;
    if (fs::exists(dst))
    {
        return dst;
    }

    switch (partition.data.user.data[1] &
            (PARTITION_PRESERVED | PARTITION_READONLY))
    {
        case PARTITION_PRESERVED:
            dst = priv->paths.prsv_loc;
            break;

        case PARTITION_READONLY:
            dst = priv->paths.ro_loc;
            break;

        default:
            dst = priv->paths.rw_loc;
    }
    dst /= partition.data.name;

    if (fs::exists(dst))
    {
        return dst;
    }

    if (flags == O_RDONLY)
    {
        dst = fs::path(priv->paths.ro_loc) / partition.data.name;
        assert(fs::exists(dst));
        return dst;
    }

    assert(flags == O_RDWR);
    auto src = fs::path(priv->paths.ro_loc) / partition.data.name;
    assert(fs::exists(src));

    MSG_DBG("RWRequest: Didn't find '%s' under '%s', copying from '%s'\n",
            partition.data.name, dst.c_str(), src.c_str());

    dst = priv->paths.rw_loc;
    if (partition.data.user.data[1] & PARTITION_PRESERVED)
    {
        dst = priv->paths.prsv_loc;
    }

    dst /= partition.data.name;
    fs::copy_file(src, dst);
    fs::permissions(dst, fs::perms::owner_write, fs::perm_options::add);

    return dst;
}

size_t Request::clamp(size_t len)
{
    size_t maxAccess = offset + len;
    size_t partSize = partition.data.size << backend->block_size_shift;
    return std::min(maxAccess, partSize) - offset;
}

/* Perform reads and writes for an entire buffer's worth of data
 *
 * Post-condition: All bytes read or written, or an error has occurred
 *
 * Yields 0 if the entire buffer was processed, otherwise -1
 */
#define fd_process_all(fn, fd, src, len)                                       \
    ({                                                                         \
        size_t __len = len;                                                    \
        ssize_t __accessed = 0;                                                \
        do                                                                     \
        {                                                                      \
            __len -= __accessed;                                               \
            __accessed = TEMP_FAILURE_RETRY(fn(fd, src, __len));               \
        } while (__len > 0 && __accessed > 0);                                 \
        __len ? -1 : 0;                                                        \
    })

ssize_t Request::read(void* dst, size_t len)
{
    len = clamp(len);

    fs::path path = getPartitionFilePath(O_RDONLY);

    MSG_INFO("Fulfilling read request against %s at offset 0x%zx into %p "
             "for %zu\n",
             path.c_str(), offset, dst, len);

    size_t fileSize = fs::file_size(path);

    size_t access_len = 0;
    if (offset < fileSize)
    {
        int fd = ::open(path.c_str(), O_RDONLY);
        if (fd == -1)
        {
            MSG_ERR("Failed to open backing file at '%s': %d\n", path.c_str(),
                    errno);
            throw std::system_error(errno, std::system_category());
        }

        int rc = lseek(fd, offset, SEEK_SET);
        if (rc < 0)
        {
            int lerrno = errno;
            close(fd);
            MSG_ERR("Failed to seek to %zu in %s (%zu bytes): %d\n", offset,
                    path.c_str(), fileSize, lerrno);
            throw std::system_error(lerrno, std::system_category());
        }

        access_len = std::min(len, fileSize - offset);
        rc = fd_process_all(::read, fd, dst, access_len);
        if (rc < 0)
        {
            int lerrno = errno;
            close(fd);
            MSG_ERR(
                "Requested %zu bytes but failed to read %zu from %s (%zu) at "
                "%zu: %d\n",
                len, access_len, path.c_str(), fileSize, offset, lerrno);
            throw std::system_error(lerrno, std::system_category());
        }

        close(fd);
    }

    /* Set any remaining buffer space to the erased state */
    memset((char*)dst + access_len, 0xff, len - access_len);

    return len;
}

ssize_t Request::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());
    }

    /* Ensure file is at least the size of the maximum access */
    fs::path path = getPartitionFilePath(O_RDWR);

    MSG_INFO("Fulfilling write request against %s at offset 0x%zx from %p "
             "for %zu\n",
             path.c_str(), offset, dst, len);

    int fd = ::open(path.c_str(), O_RDWR);
    if (fd == -1)
    {
        MSG_ERR("Failed to open backing file at '%s': %d\n", path.c_str(),
                errno);
        throw std::system_error(errno, std::system_category());
    }

    int rc = lseek(fd, offset, SEEK_SET);
    if (rc < 0)
    {
        int lerrno = errno;
        close(fd);
        MSG_ERR("Failed to seek to %zu in %s: %d\n", offset, path.c_str(),
                lerrno);
        throw std::system_error(lerrno, std::system_category());
    }

    rc = fd_process_all(::write, fd, dst, len);
    if (rc < 0)
    {
        int lerrno = errno;
        close(fd);
        MSG_ERR("Failed to write %zu bytes to %s at %zu: %d\n", len,
                path.c_str(), offset, lerrno);
        throw std::system_error(lerrno, std::system_category());
    }
    backend_set_bytemap(backend, base + offset, len, FLASH_DIRTY);

    close(fd);

    return len;
}

} // namespace virtual_pnor
} // namespace openpower
