#pragma once

#include "binarystore_interface.hpp"
#include "sys_file.hpp"

#include <unistd.h>

#include <blobs-ipmid/blobs.hpp>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>

using std::size_t;
using std::uint16_t;
using std::uint32_t;
using std::uint64_t;
using std::uint8_t;

namespace binstore
{

/**
 * @class BinaryStore instantiates a concrete implementation of
 *     BinaryStoreInterface. The dependency on file is injected through its
 *     constructor.
 */
class BinaryStore : public BinaryStoreInterface
{
  public:
    /* |CommitState| differs slightly with |StateFlags| in blob.hpp,
     * and thus is defined in the OEM space (bit 8 - 15). User can call stat()
     * to query the |CommitState| of the blob path. */
    enum CommitState
    {
        Dirty = (1 << 8), // In-memory data might not match persisted data
        Clean = (1 << 9), // In-memory data matches persisted data
        Uninitialized = (1 << 10), // Cannot find persisted data
        CommitError = (1 << 11)    // Error happened during committing
    };

    BinaryStore() = delete;
    BinaryStore(const std::string& baseBlobId, std::unique_ptr<SysFile> file,
                std::optional<uint32_t> maxSize = std::nullopt) :
        baseBlobId_(baseBlobId),
        file_(std::move(file)), maxSize(maxSize)
    {
    }

    BinaryStore(std::unique_ptr<SysFile> file, bool readOnly = false,
                std::optional<uint32_t> maxSize = std::nullopt) :
        readOnly_{readOnly},
        file_(std::move(file)), maxSize(maxSize)
    {
    }

    ~BinaryStore() = default;

    BinaryStore(const BinaryStore&) = delete;
    BinaryStore& operator=(const BinaryStore&) = delete;
    BinaryStore(BinaryStore&&) = default;
    BinaryStore& operator=(BinaryStore&&) = default;

    std::string getBaseBlobId() const override;
    bool setBaseBlobId(const std::string& baseBlobId) override;
    std::vector<std::string> getBlobIds() const override;
    bool openOrCreateBlob(const std::string& blobId, uint16_t flags) override;
    bool deleteBlob(const std::string& blobId) override;
    std::vector<uint8_t> read(uint32_t offset, uint32_t requestedSize) override;
    std::vector<uint8_t> readBlob(const std::string& blobId) const override;
    bool write(uint32_t offset, const std::vector<uint8_t>& data) override;
    bool commit() override;
    bool close() override;
    bool stat(blobs::BlobMeta* meta) override;

    /**
     * Helper factory method to create a BinaryStore instance
     * @param baseBlobId: base id for the created instance
     * @param sysFile: system file object for storing binary
     * @returns unique_ptr to constructed BinaryStore. Caller should take
     *     ownership of the instance.
     */
    static std::unique_ptr<BinaryStoreInterface> createFromConfig(
        const std::string& baseBlobId, std::unique_ptr<SysFile> file,
        std::optional<uint32_t> maxSize = std::nullopt,
        std::optional<std::string> aliasBlobBaseId = std::nullopt);

    /**
     * Helper factory method to create a BinaryStore instance
     * This function should be used with existing stores. It reads
     * the baseBlobId name from the storage.
     * @param sysFile: system file object for storing binary
     * @param readOnly: if true, open the store in read only mode
     * @returns unique_ptr to constructed BinaryStore.
     */
    static std::unique_ptr<BinaryStoreInterface>
        createFromFile(std::unique_ptr<SysFile> file, bool readOnly = true,
                       std::optional<uint32_t> maxSize = std::nullopt);

  private:
    /* Load the serialized data from sysfile if commit state is dirty.
     * Returns False if encountered error when loading */
    bool loadSerializedData(
        std::optional<std::string> aliasBlobBaseId = std::nullopt);

    std::map<std::string, std::vector<std::uint8_t>> blobs_;
    std::string baseBlobId_, currentBlob_;
    /* True if current blob is writable */
    bool writable_ = false;
    /* True if the entire store (not just individual blobs) is read only */
    bool readOnly_ = false;
    std::unique_ptr<SysFile> file_ = nullptr;
    CommitState commitState_ = CommitState::Dirty;
    std::optional<uint32_t> maxSize;
};

} // namespace binstore
