from typing import Any
from pathlib import Path
from threading import Lock
import json

from .database.jsonl_db import JsonlDB
from .database.sqlite_db import SqliteDB

lock = Lock()

class Store:
    def __init__(self,
                name: str,
                store_path: str | Path,
                database_type: str = "cache",
                ):
        self.name = name
        self.store_path = Path(store_path)
        self.database_type = database_type
        
        self.store_path.mkdir(parents=True, exist_ok=True)

        self.node_meta_path = self.store_path / "meta.json"
        self.database_path = self.store_path

        self.cache = {}
        self.db = None

        if self.database_type != "cache":
            self.load_database()

    def get_meta(self):
        try:
            with open(self.node_meta_path, "r") as f:
                node_meta = json.load(f)
                return node_meta
        except:
            return None
    
    def set_meta(self, meta: dict[str, Any]):
        with open(self.node_meta_path, "w") as f:
            json.dump(meta, f, indent=4)

    def load_database(self):
        if self.database_type == "jsonl":
            self.db = JsonlDB(self.database_path,"output")
        elif self.database_type == "sqlite":
            self.db = SqliteDB(self.database_path,"output")
        else:
            raise ValueError(f"Unsupported database type: {self.database_type}")
        
        data = self.db.get_all()
        self.cache = dict(data)
    
    def get_all_keys(self) -> list[int | str]:
        return list(self.cache.keys())

    def exists(self, key: int | str) -> bool:
        return key in self.cache

    def get(self, key: int | str) -> Any:
        return self.cache[key]

    def set(self,key: int | str,value: Any):
        with lock:
            if self.db is not None:
                self.db.set(key,value)
            self.cache[key] = value
