from __future__ import annotations

from pathlib import Path

import pytest

from cf_ontology.ontology_manager import OntologyManager
from cf_ontology.pipeline_states_store import PipelineStateStore
from cf_ontology.quad_store import QuadStore


def _pipeline_store(tmp_path: Path) -> QuadStore:
    semantics_dir = tmp_path / "semantics"
    store = QuadStore(
        db_path=semantics_dir / "cf-pipelines.duckdb",
        semantics_dir=semantics_dir,
    )
    store.init_schema(create_pipeline_tables=True)
    return store


def _state_store(tmp_path: Path) -> PipelineStateStore:
    semantics_dir = tmp_path / "semantics"
    store = PipelineStateStore(
        db_path=semantics_dir / "cf-pipeline-states.duckdb",
        semantics_dir=semantics_dir,
    )
    store.init_schema()
    return store


def test_ontology_manager_pipeline_draft_and_listing_delegates(tmp_path: Path) -> None:
    pipeline_store = _pipeline_store(tmp_path)
    state_store = _state_store(tmp_path)
    pipeline_store.create_pipeline("demo", created_by="alice")
    pipeline_store.save_draft("demo", "<s> <p> <o> .\n", saved_by="alice", message="draft")
    con = state_store._connect(read_only=False)
    try:
        con.execute(
            """
            INSERT INTO pipeline_state (
              pipeline_id,
              current_rev,
              desired_state,
              updated_at
            )
            VALUES (?, ?, ?, current_timestamp)
            """,
            ["demo", 0, "sleep"],
        )
    finally:
        con.close()

    manager = object.__new__(OntologyManager)
    manager._pipelines_store = pipeline_store
    manager._pipeline_state_store = state_store

    assert manager.load_pipeline_draft("demo") == "<s> <p> <o> .\n"
    assert manager.pipeline_draft_exists("demo") is True
    assert manager.list_pipeline_drafts()[0]["pipeline_id"] == "demo"
    pipeline_rows = manager.list_pipeline_rows()
    assert pipeline_rows == [
        {
            "pipeline_id": "demo",
            "current_rev": 0,
            "updated_at": pipeline_rows[0]["updated_at"],
            "created_by": "alice",
            "updated_by": "alice",
        }
    ]
    state_rows = manager.list_pipeline_state_rows()
    assert state_rows[0]["pipeline_id"] == "demo"
    assert state_rows[0]["state"] == "sleep"

    manager.discard_pipeline_draft("demo")
    assert manager.pipeline_draft_exists("demo") is False


def test_ontology_manager_draft_and_state_methods_raise_without_backing_stores() -> None:
    manager = object.__new__(OntologyManager)
    manager._pipelines_store = None
    manager._pipeline_state_store = None

    with pytest.raises(RuntimeError):
        manager.save_pipeline_draft("demo", "<s> <p> <o> .")
    with pytest.raises(RuntimeError):
        manager.load_pipeline_draft("demo")
    with pytest.raises(RuntimeError):
        manager.discard_pipeline_draft("demo")
    with pytest.raises(RuntimeError):
        manager.pipeline_draft_exists("demo")
    with pytest.raises(RuntimeError):
        manager.list_pipeline_drafts()
    with pytest.raises(RuntimeError):
        manager.list_pipeline_rows()
    with pytest.raises(RuntimeError):
        manager.list_pipeline_state_rows()
