/*
 * 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 <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(const char* start, size_t length)
{
    if (!start)
    {
        return "";
    }

    auto end = static_cast<const char*>(std::memchr(start, '\0', length));
    if (end != &start[length - 1])
    {
        return "";
    }

    return (end == nullptr) ? std::string() : std::string(start, end);
}

ipmi_ret_t getBlobCount(ManagerInterface* mgr, const uint8_t* reqBuf,
                        uint8_t* replyCmdBuf, size_t* dataLen)
{
    struct BmcBlobCountRx resp;
    resp.crc = 0;
    resp.blobCount = mgr->buildBlobList();

    /* Copy the response into the reply buffer */
    std::memcpy(replyCmdBuf, &resp, sizeof(resp));
    (*dataLen) = sizeof(resp);

    return IPMI_CC_OK;
}

ipmi_ret_t enumerateBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                         uint8_t* replyCmdBuf, size_t* dataLen)
{
    /* Verify datalen is >= sizeof(request) */
    struct BmcBlobEnumerateTx request;
    auto reply = reinterpret_cast<struct BmcBlobEnumerateRx*>(replyCmdBuf);

    std::memcpy(&request, reqBuf, sizeof(request));

    std::string blobId = mgr->getBlobId(request.blobIdx);
    if (blobId == "")
    {
        return IPMI_CC_INVALID;
    }

    /* TODO(venture): Need to do a hard-code check against the maximum
     * reply buffer size. */
    reply->crc = 0;
    /* Explicilty copies the NUL-terminator. */
    std::memcpy(&reply->blobId, blobId.c_str(), blobId.length() + 1);

    (*dataLen) = sizeof(reply->crc) + blobId.length() + 1;

    return IPMI_CC_OK;
}

ipmi_ret_t openBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                    uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    auto request = reinterpret_cast<const struct BmcBlobOpenTx*>(reqBuf);
    uint16_t session;

    std::string path = stringFromBuffer(
        request->blobId, (requestLen - sizeof(struct BmcBlobOpenTx)));
    if (path.empty())
    {
        return IPMI_CC_INVALID;
    }

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

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

    std::memcpy(replyCmdBuf, &reply, sizeof(reply));
    (*dataLen) = sizeof(reply);

    return IPMI_CC_OK;
}

ipmi_ret_t closeBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                     uint8_t* replyCmdBuf, size_t* dataLen)
{
    struct BmcBlobCloseTx request;
    std::memcpy(&request, reqBuf, sizeof(request));

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

    (*dataLen) = 0;
    return IPMI_CC_OK;
}

ipmi_ret_t deleteBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                      uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    auto request = reinterpret_cast<const struct BmcBlobDeleteTx*>(reqBuf);

    std::string path = stringFromBuffer(
        request->blobId, (requestLen - sizeof(struct BmcBlobDeleteTx)));
    if (path.empty())
    {
        return IPMI_CC_INVALID;
    }

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

    (*dataLen) = 0;
    return IPMI_CC_OK;
}

static ipmi_ret_t returnStatBlob(struct BlobMeta* meta, uint8_t* replyCmdBuf,
                                 size_t* dataLen)
{
    struct BmcBlobStatRx reply;
    reply.crc = 0;
    reply.blobState = meta->blobState;
    reply.size = meta->size;
    reply.metadataLen = meta->metadata.size();

    std::memcpy(replyCmdBuf, &reply, sizeof(reply));

    /* If there is metadata, copy it over. */
    if (meta->metadata.size())
    {
        uint8_t* metadata = &replyCmdBuf[sizeof(reply)];
        std::memcpy(metadata, meta->metadata.data(), reply.metadataLen);
    }

    (*dataLen) = sizeof(reply) + reply.metadataLen;
    return IPMI_CC_OK;
}

ipmi_ret_t statBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                    uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    auto request = reinterpret_cast<const struct BmcBlobStatTx*>(reqBuf);

    std::string path = stringFromBuffer(
        request->blobId, (requestLen - sizeof(struct BmcBlobStatTx)));
    if (path.empty())
    {
        return IPMI_CC_INVALID;
    }

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

    return returnStatBlob(&meta, replyCmdBuf, dataLen);
}

ipmi_ret_t sessionStatBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                           uint8_t* replyCmdBuf, size_t* dataLen)
{
    struct BmcBlobSessionStatTx request;
    std::memcpy(&request, reqBuf, sizeof(request));

    /* Attempt to stat. */
    struct BlobMeta meta;

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

    return returnStatBlob(&meta, replyCmdBuf, dataLen);
}

ipmi_ret_t commitBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                      uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    auto request = reinterpret_cast<const struct BmcBlobCommitTx*>(reqBuf);

    /* Sanity check the commitDataLen */
    if (request->commitDataLen > (requestLen - sizeof(struct BmcBlobCommitTx)))
    {
        return IPMI_CC_INVALID;
    }

    std::vector<uint8_t> data(request->commitDataLen);
    std::memcpy(data.data(), request->commitData, request->commitDataLen);

    if (!mgr->commit(request->sessionId, data))
    {
        return IPMI_CC_INVALID;
    }

    (*dataLen) = 0;
    return IPMI_CC_OK;
}

ipmi_ret_t readBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                    uint8_t* replyCmdBuf, size_t* dataLen)
{
    struct BmcBlobReadTx request;
    std::memcpy(&request, reqBuf, sizeof(request));

    /* TODO(venture): Verify requestedSize can fit in a returned IPMI packet.
     */

    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.
     */
    (*dataLen) = sizeof(struct BmcBlobReadRx);

    if (result.size())
    {
        uint8_t* output = &replyCmdBuf[sizeof(struct BmcBlobReadRx)];
        std::memcpy(output, result.data(), result.size());

        (*dataLen) = sizeof(struct BmcBlobReadRx) + result.size();
    }

    return IPMI_CC_OK;
}

ipmi_ret_t writeBlob(ManagerInterface* mgr, const uint8_t* reqBuf,
                     uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    auto request = reinterpret_cast<const struct BmcBlobWriteTx*>(reqBuf);

    uint32_t size = requestLen - sizeof(struct BmcBlobWriteTx);
    std::vector<uint8_t> data(size);

    std::memcpy(data.data(), request->data, size);

    /* Attempt to write the bytes. */
    if (!mgr->write(request->sessionId, request->offset, data))
    {
        return IPMI_CC_INVALID;
    }

    return IPMI_CC_OK;
}

ipmi_ret_t writeMeta(ManagerInterface* mgr, const uint8_t* reqBuf,
                     uint8_t* replyCmdBuf, size_t* dataLen)
{
    size_t requestLen = (*dataLen);
    struct BmcBlobWriteMetaTx request;

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

    /* Determine number of bytes of metadata to write. */
    uint32_t size = requestLen - sizeof(request);

    /* Nothing really else to validate, we just copy those bytes. */
    std::vector<uint8_t> data(size);
    std::memcpy(data.data(), &reqBuf[sizeof(request)], size);

    /* Attempt to write the bytes. */
    if (!mgr->writeMeta(request.sessionId, request.offset, data))
    {
        return IPMI_CC_INVALID;
    }

    return IPMI_CC_OK;
}

} // namespace blobs
