#pragma once

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

#include <unistd.h>

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

#include "binaryblob.pb.h"

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)
    {
        blob_.set_blob_base_id(baseBlobId_);
        if (maxSize)
        {
            blob_.set_max_size_bytes(*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)
    {
        if (maxSize)
        {
            blob_.set_max_size_bytes(*maxSize);
        }
    }

    ~BinaryStore() = default;

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

    std::string getBaseBlobId() const 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);

    /**
     * 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::string baseBlobId_;
    binaryblobproto::BinaryBlobBase blob_;
    binaryblobproto::BinaryBlob* currentBlob_ = nullptr;
    /* 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
