/*
 * Copyright 2019 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "p2a.hpp"

#include "data.hpp"
#include "flags.hpp"
#include "pci.hpp"
#include "tool_errors.hpp"

#include <ipmiblob/blob_errors.hpp>
#include <stdplus/handle/managed.hpp>

#include <cstdint>
#include <cstring>
#include <format>
#include <memory>
#include <span>
#include <string>

namespace host_tool
{

namespace
{

/** @brief RAII wrapper and its destructor for opening a file descriptor */
static void closeFd(int&& fd, const internal::Sys* const& sys)
{
    sys->close(fd);
}
using Fd = stdplus::Managed<int, const internal::Sys* const>::Handle<closeFd>;

} // namespace

bool P2aDataHandler::sendContents(const std::string& input,
                                  std::uint16_t session)
{
    std::unique_ptr<PciBridgeIntf> bridge;
    ipmi_flash::PciConfigResponse pciResp;
    std::int64_t fileSize;

    try
    {
        bridge = std::make_unique<NuvotonPciBridge>(pci, skipBridgeDisable);
    }
    catch (const NotFoundException& e)
    {}

    try
    {
        bridge = std::make_unique<AspeedPciBridge>(pci, skipBridgeDisable);
    }
    catch (const NotFoundException& e)
    {}

    if (!bridge)
    {
        throw NotFoundException("supported PCI device");
    }

    /* Read the configuration via blobs metadata (stat). */
    ipmiblob::StatResponse stat = blob->getStat(session);
    if (stat.metadata.size() != sizeof(ipmi_flash::PciConfigResponse))
    {
        throw ToolException("Didn't receive expected size of metadata for "
                            "PCI Configuration response");
    }

    std::memcpy(&pciResp, stat.metadata.data(), sizeof(pciResp));
    bridge->configure(pciResp);

    /* For data blocks in 64kb, stage data, and send blob write command. */
    Fd inputFd(sys->open(input.c_str(), 0), sys);
    if (*inputFd < 0)
    {
        (void)inputFd.release();
        throw internal::errnoException(
            std::format("Error opening file '{}'", input));
    }

    fileSize = sys->getSize(input.c_str());
    progress->start(fileSize);

    std::vector<std::uint8_t> readBuffer(bridge->getDataLength());

    int bytesRead = 0;
    std::uint32_t offset = 0;

    do
    {
        bytesRead = sys->read(*inputFd, readBuffer.data(), readBuffer.size());
        if (bytesRead > 0)
        {
            bridge->write(
                std::span<const std::uint8_t>(readBuffer.data(), bytesRead));

            /* Ok, so the data is staged, now send the blob write with the
             * details.
             */
            struct ipmi_flash::ExtChunkHdr chunk;
            chunk.length = bytesRead;
            std::vector<std::uint8_t> chunkBytes(sizeof(chunk));
            std::memcpy(chunkBytes.data(), &chunk, sizeof(chunk));

            /* This doesn't return anything on success. */
            blob->writeBytes(session, offset, chunkBytes);
            offset += bytesRead;
            progress->updateProgress(bytesRead);
        }
    } while (bytesRead > 0);

    progress->finish();
    return true;
}

} // namespace host_tool
