#include "example/example.hpp"

#include <algorithm>
#include <cstring>
#include <string>
#include <vector>

namespace blobs
{

constexpr char ExampleBlobHandler::supportedPath[];

ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
{
    auto search = sessions.find(id);
    if (search == sessions.end())
    {
        return nullptr;
    }
    /* Not thread-safe, however, the blob handler deliberately assumes serial
     * execution. */
    return &search->second;
}

bool ExampleBlobHandler::canHandleBlob(const std::string& path)
{
    return (path == supportedPath);
}

std::vector<std::string> ExampleBlobHandler::getBlobIds()
{
    return {supportedPath};
}

bool ExampleBlobHandler::deleteBlob(const std::string& path)
{
    return false;
}

bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
{
    return false;
}

bool ExampleBlobHandler::open(uint16_t session, uint16_t flags,
                              const std::string& path)
{
    if (!canHandleBlob(path))
    {
        return false;
    }

    auto findSess = sessions.find(session);
    if (findSess != sessions.end())
    {
        /* This session is already active. */
        return false;
    }
    sessions[session] = ExampleBlob(session, flags);
    return true;
}

std::vector<uint8_t> ExampleBlobHandler::read(uint16_t session, uint32_t offset,
                                              uint32_t requestedSize)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return std::vector<uint8_t>();
    }

    /* Is the offset beyond the array? */
    if (offset >= sizeof(sess->buffer))
    {
        return std::vector<uint8_t>();
    }

    /* Determine how many bytes we can read from the offset.
     * In this case, if they read beyond "size" we allow it.
     */
    uint32_t remain = sizeof(sess->buffer) - offset;
    uint32_t numBytes = std::min(remain, requestedSize);
    /* Copy the bytes! */
    std::vector<uint8_t> result(numBytes);
    std::memcpy(result.data(), &sess->buffer[offset], numBytes);
    return result;
}

bool ExampleBlobHandler::write(uint16_t session, uint32_t offset,
                               const std::vector<uint8_t>& data)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return false;
    }
    /* Is the offset beyond the array? */
    if (offset >= sizeof(sess->buffer))
    {
        return false;
    }
    /* Determine whether all their bytes will fit. */
    uint32_t remain = sizeof(sess->buffer) - offset;
    if (data.size() > remain)
    {
        return false;
    }
    sess->length =
        std::max(offset + data.size(),
                 static_cast<std::vector<uint8_t>::size_type>(sess->length));
    std::memcpy(&sess->buffer[offset], data.data(), data.size());
    return true;
}

bool ExampleBlobHandler::commit(uint16_t session,
                                const std::vector<uint8_t>& data)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return false;
    }

    /* Do something with the staged data!. */

    return false;
}

bool ExampleBlobHandler::close(uint16_t session)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return false;
    }

    sessions.erase(session);
    return true;
}

bool ExampleBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return false;
    }
    if (!meta)
    {
        return false;
    }
    meta->size = sess->length;
    meta->blobState = sess->state;
    return true;
}

bool ExampleBlobHandler::expire(uint16_t session)
{
    ExampleBlob* sess = getSession(session);
    if (!sess)
    {
        return false;
    }
    /* TODO: implement session expiration behavior. */
    return false;
}

} // namespace blobs
