#include "example/example.hpp"

#include <algorithm>
#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
