#pragma once

#include "blobs.hpp"

#include <ctime>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace blobs
{

struct SessionInfo
{
    SessionInfo() = default;
    SessionInfo(const std::string& path, GenericBlobInterface* handler,
                uint16_t flags) :
        blobId(path),
        handler(handler), flags(flags)
    {
    }
    ~SessionInfo() = default;

    std::string blobId;
    GenericBlobInterface* handler;
    uint16_t flags;
};

class ManagerInterface
{
  public:
    virtual ~ManagerInterface() = default;

    virtual bool
        registerHandler(std::unique_ptr<GenericBlobInterface> handler) = 0;

    virtual uint32_t buildBlobList() = 0;

    virtual std::string getBlobId(uint32_t index) = 0;

    virtual bool open(uint16_t flags, const std::string& path,
                      uint16_t* session) = 0;

    virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0;

    virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0;

    virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0;

    virtual bool close(uint16_t session) = 0;

    virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset,
                                      uint32_t requestedSize) = 0;

    virtual bool write(uint16_t session, uint32_t offset,
                       const std::vector<uint8_t>& data) = 0;

    virtual bool deleteBlob(const std::string& path) = 0;
};

/**
 * Blob Manager used to store handlers and sessions.
 */
class BlobManager : public ManagerInterface
{
  public:
    BlobManager()
    {
        next = static_cast<uint16_t>(std::time(nullptr));
    };

    ~BlobManager() = default;
    /* delete copy constructor & assignment operator, only support move
     * operations.
     */
    BlobManager(const BlobManager&) = delete;
    BlobManager& operator=(const BlobManager&) = delete;
    BlobManager(BlobManager&&) = default;
    BlobManager& operator=(BlobManager&&) = default;

    /**
     * Register a handler.  We own the pointer.
     *
     * @param[in] handler - a pointer to a blob handler.
     * @return bool - true if registered.
     */
    bool
        registerHandler(std::unique_ptr<GenericBlobInterface> handler) override;

    /**
     * Builds the blobId list for enumeration.
     *
     * @return lowest value returned is 0, otherwise the number of
     * blobIds.
     */
    uint32_t buildBlobList() override;

    /**
     * Grabs the blobId for the indexed blobId.
     *
     * @param[in] index - the index into the blobId cache.
     * @return string - the blobId or empty string on failure.
     */
    std::string getBlobId(uint32_t index) override;

    /**
     * Attempts to open the file specified and associates with a session.
     *
     * @param[in] flags - the flags to pass to open.
     * @param[in] path - the file path to open.
     * @param[in,out] session - pointer to store the session on success.
     * @return bool - true if able to open.
     */
    bool open(uint16_t flags, const std::string& path,
              uint16_t* session) override;

    /**
     * Attempts to retrieve a BlobMeta for the specified path.
     *
     * @param[in] path - the file path for stat().
     * @param[in,out] meta - a pointer to store the metadata.
     * @return bool - true if able to retrieve the information.
     */
    bool stat(const std::string& path, struct BlobMeta* meta) override;

    /**
     * Attempts to retrieve a BlobMeta for a given session.
     *
     * @param[in] session - the session for this command.
     * @param[in,out] meta - a pointer to store the metadata.
     * @return bool - true if able to retrieve the information.
     */
    bool stat(uint16_t session, struct BlobMeta* meta) override;

    /**
     * Attempt to commit a blob for a given session.
     *
     * @param[in] session - the session for this command.
     * @param[in] data - an optional commit blob.
     * @return bool - true if the commit succeeds.
     */
    bool commit(uint16_t session, const std::vector<uint8_t>& data) override;

    /**
     * Attempt to close a session.  If the handler returns a failure
     * in closing, the session is kept open.
     *
     * @param[in] session - the session for this command.
     * @return bool - true if the session was closed.
     */
    bool close(uint16_t session) override;

    /**
     * Attempt to read bytes from the blob.  If there's a failure, such as
     * an invalid offset it'll just return 0 bytes.
     *
     * @param[in] session - the session for this command.
     * @param[in] offset - the offset from which to read.
     * @param[in] requestedSize - the number of bytes to try and read.
     * @return the bytes read.
     */
    std::vector<uint8_t> read(uint16_t session, uint32_t offset,
                              uint32_t requestedSize) override;

    /**
     * Attempt to write to a blob.  The manager does not track whether
     * the session opened the file for writing.
     *
     * @param[in] session - the session for this command.
     * @param[in] offset - the offset into the blob to write.
     * @param[in] data - the bytes to write to the blob.
     * @return bool - true if the write succeeded.
     */
    bool write(uint16_t session, uint32_t offset,
               const std::vector<uint8_t>& data) override;

    /**
     * Attempt to delete a blobId.  This method will just call the
     * handler, which will return failure if the blob doesn't support
     * deletion.  This command will also fail if there are any open
     * sessions against the specific blob.
     *
     * In the case where they specify a folder, such as /blob/skm where
     * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager
     * may see there are on open sessions to that specific path and will
     * call the handler.  In this case, the handler is responsible for
     * handling any checks or logic.
     *
     * @param[in] path - the blobId path.
     * @return bool - true if delete was successful.
     */
    bool deleteBlob(const std::string& path) override;

    /**
     * Attempts to return a valid unique session id.
     *
     * @param[in,out] - pointer to the session.
     * @return bool - true if able to allocate.
     */
    bool getSession(uint16_t* session);

    /**
     * Given a file path will return first handler to answer that it owns
     * it.
     *
     * @param[in] path - the file path.
     * @return pointer to the handler or nullptr if not found.
     */
    GenericBlobInterface* getHandler(const std::string& path);

    /**
     * Given a session id will return associated handler.
     *
     * @param[in] session - the session.
     * @return pointer to the handler or nullptr if not found.
     */
    GenericBlobInterface* getHandler(uint16_t session);

    /**
     * Given a session id will return associated metadata, including
     * the handler and the flags passed into open.
     *
     * @param[in] session - the session.
     * @return pointer to the information or nullptr if not found.
     */
    SessionInfo* getSessionInfo(uint16_t session);

    /**
     * Given a session id will return associated path.
     *
     * @param[in] session - the session.
     * @return the path or "" on failure.
     */
    std::string getPath(uint16_t session) const;

  private:
    void incrementOpen(const std::string& path);
    void decrementOpen(const std::string& path);
    int getOpen(const std::string& path) const;

    /* The next session ID to use */
    uint16_t next;
    /* Temporary list of blobIds used for enumeration. */
    std::vector<std::string> ids;
    /* List of Blob handler. */
    std::vector<std::unique_ptr<GenericBlobInterface>> handlers;
    /* Mapping of session ids to blob handlers and the path used with open.
     */
    std::unordered_map<uint16_t, SessionInfo> sessions;
    /* Mapping of open blobIds */
    std::unordered_map<std::string, int> openFiles;
};
} // namespace blobs
