/*
 * 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 "ipmi.hpp"

#include <cstring>
#include <span>
#include <string>
#include <unordered_map>

namespace blobs
{

bool validateRequestLength(BlobOEMCommands command, size_t requestLen)
{
    /* The smallest string is one letter and the nul-terminator. */
    static const int kMinStrLen = 2;

    static const std::unordered_map<BlobOEMCommands, size_t> minimumLengths = {
        {BlobOEMCommands::bmcBlobEnumerate, sizeof(struct BmcBlobEnumerateTx)},
        {BlobOEMCommands::bmcBlobOpen,
         sizeof(struct BmcBlobOpenTx) + kMinStrLen},
        {BlobOEMCommands::bmcBlobClose, sizeof(struct BmcBlobCloseTx)},
        {BlobOEMCommands::bmcBlobDelete,
         sizeof(struct BmcBlobDeleteTx) + kMinStrLen},
        {BlobOEMCommands::bmcBlobStat,
         sizeof(struct BmcBlobStatTx) + kMinStrLen},
        {BlobOEMCommands::bmcBlobSessionStat,
         sizeof(struct BmcBlobSessionStatTx)},
        {BlobOEMCommands::bmcBlobCommit, sizeof(struct BmcBlobCommitTx)},
        {BlobOEMCommands::bmcBlobRead, sizeof(struct BmcBlobReadTx)},
        {BlobOEMCommands::bmcBlobWrite,
         sizeof(struct BmcBlobWriteTx) + sizeof(uint8_t)},
        {BlobOEMCommands::bmcBlobWriteMeta,
         sizeof(struct BmcBlobWriteMetaTx) + sizeof(uint8_t)},
    };

    auto results = minimumLengths.find(command);
    if (results == minimumLengths.end())
    {
        /* Valid length by default if we don't care. */
        return true;
    }

    /* If the request is shorter than the minimum, it's invalid. */
    if (requestLen < results->second)
    {
        return false;
    }

    return true;
}

std::string stringFromBuffer(std::span<const uint8_t> data)
{
    if (data.empty() || data.back() != '\0')
    {
        return std::string();
    }

    // Last index is nul-terminator.
    return std::string(data.begin(), data.end() - 1);
}

Resp getBlobCount(ManagerInterface* mgr, std::span<const uint8_t>)
{
    struct BmcBlobCountRx resp;
    resp.crc = 0;
    resp.blobCount = mgr->buildBlobList();

    /* Copy the response into the reply buffer */
    std::vector<uint8_t> output(sizeof(BmcBlobCountRx), 0);
    std::memcpy(output.data(), &resp, sizeof(resp));

    return ipmi::responseSuccess(output);
}

Resp enumerateBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    /* Verify datalen is >= sizeof(request) */
    struct BmcBlobEnumerateTx request;

    std::memcpy(&request, data.data(), sizeof(request));

    std::string blobId = mgr->getBlobId(request.blobIdx);
    if (blobId.empty())
    {
        return ipmi::responseInvalidFieldRequest();
    }

    std::vector<uint8_t> output(sizeof(BmcBlobEnumerateRx), 0);
    output.insert(output.end(), blobId.c_str(),
                  blobId.c_str() + blobId.length() + 1);
    return ipmi::responseSuccess(output);
}

Resp openBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    auto request = reinterpret_cast<const struct BmcBlobOpenTx*>(data.data());
    uint16_t session;

    std::string path = stringFromBuffer(data.subspan(sizeof(BmcBlobOpenTx)));
    if (path.empty())
    {
        return ipmi::responseReqDataLenInvalid();
    }

    /* Attempt to open. */
    if (!mgr->open(request->flags, path, &session))
    {
        return ipmi::responseUnspecifiedError();
    }

    struct BmcBlobOpenRx reply;
    reply.crc = 0;
    reply.sessionId = session;

    std::vector<uint8_t> output(sizeof(BmcBlobOpenRx), 0);
    std::memcpy(output.data(), &reply, sizeof(reply));
    return ipmi::responseSuccess(output);
}

Resp closeBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    struct BmcBlobCloseTx request;
    if (data.size() < sizeof(request))
    {
        return ipmi::responseReqDataLenInvalid();
    }
    std::memcpy(&request, data.data(), sizeof(request));

    /* Attempt to close. */
    if (!mgr->close(request.sessionId))
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess(std::vector<uint8_t>{});
}

Resp deleteBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    std::string path = stringFromBuffer(data.subspan(sizeof(BmcBlobDeleteTx)));
    if (path.empty())
    {
        return ipmi::responseReqDataLenInvalid();
    }

    /* Attempt to delete. */
    if (!mgr->deleteBlob(path))
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess(std::vector<uint8_t>{});
}

static Resp returnStatBlob(BlobMeta* meta)
{
    struct BmcBlobStatRx reply;
    reply.crc = 0;
    reply.blobState = meta->blobState;
    reply.size = meta->size;
    reply.metadataLen = meta->metadata.size();

    std::vector<uint8_t> output(sizeof(BmcBlobStatRx), 0);
    std::memcpy(output.data(), &reply, sizeof(reply));

    /* If there is metadata, insert it to output. */
    if (!meta->metadata.empty())
    {
        output.insert(output.end(), meta->metadata.begin(),
                      meta->metadata.end());
    }
    return ipmi::responseSuccess(output);
}

Resp statBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    std::string path = stringFromBuffer(data.subspan(sizeof(BmcBlobStatTx)));
    if (path.empty())
    {
        return ipmi::responseReqDataLenInvalid();
    }

    /* Attempt to stat. */
    BlobMeta meta;
    if (!mgr->stat(path, &meta))
    {
        return ipmi::responseUnspecifiedError();
    }

    return returnStatBlob(&meta);
}

Resp sessionStatBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    struct BmcBlobSessionStatTx request;
    if (data.size() < sizeof(request))
    {
        return ipmi::responseReqDataLenInvalid();
    }
    std::memcpy(&request, data.data(), sizeof(request));

    /* Attempt to stat. */
    BlobMeta meta;

    if (!mgr->stat(request.sessionId, &meta))
    {
        return ipmi::responseUnspecifiedError();
    }

    return returnStatBlob(&meta);
}

Resp commitBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    auto request = reinterpret_cast<const struct BmcBlobCommitTx*>(data.data());

    /* Sanity check the commitDataLen */
    if (request->commitDataLen > (data.size() - sizeof(struct BmcBlobCommitTx)))
    {
        return ipmi::responseReqDataLenInvalid();
    }

    data = data.subspan(sizeof(struct BmcBlobCommitTx), request->commitDataLen);

    if (!mgr->commit(request->sessionId,
                     std::vector<uint8_t>(data.begin(), data.end())))
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess(std::vector<uint8_t>{});
}

Resp readBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    struct BmcBlobReadTx request;
    if (data.size() < sizeof(request))
    {
        return ipmi::responseReqDataLenInvalid();
    }
    std::memcpy(&request, data.data(), sizeof(request));

    std::vector<uint8_t> result =
        mgr->read(request.sessionId, request.offset, request.requestedSize);

    /* If the Read fails, it returns success but with only the crc and 0 bytes
     * of data.
     * If there was data returned, copy into the reply buffer.
     */
    std::vector<uint8_t> output(sizeof(BmcBlobReadRx), 0);

    if (!result.empty())
    {
        output.insert(output.end(), result.begin(), result.end());
    }

    return ipmi::responseSuccess(output);
}

Resp writeBlob(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    auto request = reinterpret_cast<const struct BmcBlobWriteTx*>(data.data());
    data = data.subspan(sizeof(struct BmcBlobWriteTx));

    /* Attempt to write the bytes. */
    if (!mgr->write(request->sessionId, request->offset,
                    std::vector<uint8_t>(data.begin(), data.end())))
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess(std::vector<uint8_t>{});
}

Resp writeMeta(ManagerInterface* mgr, std::span<const uint8_t> data)
{
    struct BmcBlobWriteMetaTx request;
    if (data.size() < sizeof(request))
    {
        return ipmi::responseReqDataLenInvalid();
    }

    /* Copy over the request. */
    std::memcpy(&request, data.data(), sizeof(request));

    /* Nothing really else to validate, we just copy those bytes. */
    data = data.subspan(sizeof(struct BmcBlobWriteMetaTx));

    /* Attempt to write the bytes. */
    if (!mgr->writeMeta(request.sessionId, request.offset,
                        std::vector<uint8_t>(data.begin(), data.end())))
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess(std::vector<uint8_t>{});
}

} // namespace blobs
