/*
 * Copyright 2018 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 "process.hpp"

#include "ipmi.hpp"

#include <ipmiblob/crc.hpp>
#include <ipmid/api-types.hpp>

#include <cstring>
#include <span>
#include <unordered_map>
#include <utility>
#include <vector>

namespace blobs
{

/* Used by all commands with data. */
struct BmcRx
{
    uint16_t crc;
    uint8_t data; /* one byte minimum of data. */
} __attribute__((packed));

static const std::unordered_map<BlobOEMCommands, IpmiBlobHandler> handlers = {
    {BlobOEMCommands::bmcBlobGetCount, getBlobCount},
    {BlobOEMCommands::bmcBlobEnumerate, enumerateBlob},
    {BlobOEMCommands::bmcBlobOpen, openBlob},
    {BlobOEMCommands::bmcBlobRead, readBlob},
    {BlobOEMCommands::bmcBlobWrite, writeBlob},
    {BlobOEMCommands::bmcBlobCommit, commitBlob},
    {BlobOEMCommands::bmcBlobClose, closeBlob},
    {BlobOEMCommands::bmcBlobDelete, deleteBlob},
    {BlobOEMCommands::bmcBlobStat, statBlob},
    {BlobOEMCommands::bmcBlobSessionStat, sessionStatBlob},
    {BlobOEMCommands::bmcBlobWriteMeta, writeMeta},
};

IpmiBlobHandler validateBlobCommand(uint8_t cmd, std::span<const uint8_t> data)
{
    size_t requestLength = data.size();
    /* We know dataLen is at least 1 already */
    auto command = static_cast<BlobOEMCommands>(cmd);

    /* Validate it's at least well-formed. */
    if (!validateRequestLength(command, requestLength))
    {
        return [](ManagerInterface*, std::span<const uint8_t>) {
            return ipmi::responseReqDataLenInvalid();
        };
    }

    /* If there is a payload. */
    if (requestLength > sizeof(cmd))
    {
        /* Verify the request includes: command, crc16, data */
        if (requestLength < sizeof(struct BmcRx))
        {
            return [](ManagerInterface*, std::span<const uint8_t>) {
                return ipmi::responseReqDataLenInvalid();
            };
        }

        /* We don't include the command byte at offset 0 as part of the crc
         * payload area or the crc bytes at the beginning.
         */
        size_t requestBodyLen = requestLength - 3;

        /* We start after the command byte. */
        std::vector<uint8_t> bytes(requestBodyLen);

        /* It likely has a well-formed payload.
         * Get the first two bytes of the request for crc.
         */
        uint16_t crc;
        if (data.size() < sizeof(crc))
        {
            return [](ManagerInterface*, std::span<const uint8_t>) {
                return ipmi::responseReqDataLenInvalid();
            };
        }
        std::memcpy(&crc, data.data(), sizeof(crc));

        /* Set the in-place CRC to zero.
         * Remove the first two bytes for crc and get the reset of the request.
         */
        data = data.subspan(sizeof(crc));

        /* Crc expected but didn't match. */
        if (crc != ipmiblob::generateCrc(
                       std::vector<uint8_t>(data.begin(), data.end())))
        {
            return [](ManagerInterface*, std::span<const uint8_t>) {
                return ipmi::responseUnspecifiedError();
            };
        };
    }

    /* Grab the corresponding handler for the command. */
    auto found = handlers.find(command);
    if (found == handlers.end())
    {
        return [](ManagerInterface*, std::span<const uint8_t>) {
            return ipmi::responseInvalidFieldRequest();
        };
    }

    return found->second;
}

Resp processBlobCommand(IpmiBlobHandler cmd, ManagerInterface* mgr,
                        std::span<const uint8_t> data, size_t maxSize)
{
    Resp result = cmd(mgr, data);
    if (std::get<0>(result) != ipmi::ccSuccess)
    {
        return result;
    }

    std::vector<uint8_t>& response = std::get<0>(
        // std::variant<std::vector<uint8_t>>
        *std::get<1>(result));
    size_t replyLength = response.size();

    /* The command, whatever it was, returned success. */
    if (replyLength == 0)
    {
        return result;
    }

    /* Read can return 0 bytes, and just a CRC, otherwise you need a CRC and 1
     * byte, therefore the limit is 2 bytes.
     */
    if (replyLength < (sizeof(uint16_t)))
    {
        return ipmi::responseUnspecifiedError();
    }

    /* Make sure the reply size fits the ipmi buffer */
    if (replyLength > maxSize)
    {
        return ipmi::responseResponseError();
    }

    /* The command, whatever it was, replied, so let's set the CRC. */
    std::span<const uint8_t> responseView = response;
    responseView = responseView.subspan(sizeof(uint16_t));
    std::vector<std::uint8_t> crcBuffer(responseView.begin(),
                                        responseView.end());
    /* Copy the CRC into place. */
    uint16_t crcValue = ipmiblob::generateCrc(crcBuffer);
    if (response.size() < sizeof(crcValue))
    {
        return ipmi::responseReqDataLenInvalid();
    }
    std::memcpy(response.data(), &crcValue, sizeof(crcValue));

    return result;
}

Resp handleBlobCommand(uint8_t cmd, std::vector<uint8_t> data, size_t maxSize)
{
    /* on failure rc is set to the corresponding IPMI error. */
    return processBlobCommand(validateBlobCommand(cmd, data), getBlobManager(),
                              data, maxSize);
}

} // namespace blobs
