#ifndef DATABASE_HPP
#define DATABASE_HPP

#include <filesystem>
#include <string>
#include <nlohmann/json.hpp>

typedef struct sqlite3 sqlite3;

namespace simple_object_storage {

class dbEntry {
    public:
        std::string hash; // unique primary key
        std::vector<std::string> labeltags; // multiple label:tag pairs
        nlohmann::json metadata;
};

class Database {
    public:
        static const int CURRENT_VERSION = 3;
        
        Database(const std::filesystem::path& path);
        ~Database();
        bool remove_by_hash(const std::string& hash);
        bool get(const std::string& hash_or_labeltag, dbEntry& entry);
        bool list(std::vector<dbEntry>& entries);
        bool list_by_label(const std::string& label, std::vector<dbEntry>& entries);
        bool update_or_insert(const dbEntry& entry);
    private:
        std::filesystem::path path_;
        sqlite3* db_;
        
        bool createVersionTable();
        bool getVersion(int& version);
        bool setVersion(int version);
        bool migrate(int from_version, int to_version);
        bool createObjectsTable();

        // New utility functions
        bool merge_existing_entry(const dbEntry& existing, const dbEntry& new_entry, dbEntry& merged);
        bool insert_new_entry(const dbEntry& entry);
        bool handle_tag_conflicts(const dbEntry& entry);

        bool run_sql_text(const std::string& sql, const std::string& bind_text, dbEntry& entry);
};

} // namespace simple_object_storage

#endif // DATABASE_HPP