from __future__ import annotations

import json
import os
import sqlite3
from pathlib import Path
from typing import Any, Iterable

BASE_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = BASE_DIR.parent
SHARED_DIR = Path(os.getenv("ORIGUS_SHARED_DIR", PROJECT_ROOT / "shared"))
CORE_ROOT = Path(os.getenv("ORIGUS_CORE_ROOT", SHARED_DIR / "core"))
DB_PATH = Path(os.getenv("ORIGUS_CORE_DB", CORE_ROOT / "core.db"))
SOURCE_ROOT = Path(os.getenv("ORIGUS_CORE_SOURCES", CORE_ROOT / "sources"))
SECRETS_ROOT = Path(os.getenv("ORIGUS_CORE_SECRETS", CORE_ROOT / "secrets"))
INTERNAL_TOKEN_FILE = Path(os.getenv("ORIGUS_CORE_TOKEN_FILE", CORE_ROOT / ".internal_token"))
MASTER_KEY_FILE = Path(os.getenv("ORIGUS_CORE_KEY_FILE", CORE_ROOT / ".secret_key"))

def ensure_dirs() -> None:
    for p in (CORE_ROOT, SOURCE_ROOT, SECRETS_ROOT):
        p.mkdir(parents=True, exist_ok=True)

def connect() -> sqlite3.Connection:
    ensure_dirs()
    con = sqlite3.connect(DB_PATH, timeout=15)
    con.row_factory = sqlite3.Row
    con.execute("PRAGMA foreign_keys=ON")
    con.execute("PRAGMA journal_mode=WAL")
    con.execute("PRAGMA busy_timeout=5000")
    return con

def json_load(value: str | None, default: Any = None) -> Any:
    if not value:
        return default
    try:
        return json.loads(value)
    except Exception:
        return default

def fetchall(sql: str, params: Iterable[Any] = ()) -> list[dict[str, Any]]:
    with connect() as con:
        return [dict(r) for r in con.execute(sql, tuple(params)).fetchall()]

def fetchone(sql: str, params: Iterable[Any] = ()) -> dict[str, Any] | None:
    with connect() as con:
        row = con.execute(sql, tuple(params)).fetchone()
        return dict(row) if row else None
