// 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::experimental::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::add_perms | fs::perms::owner_write);

    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
