from __future__ import annotations

import sqlite3
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from src.quant_engine.data_collection_store_v1 import (
    CollectionRun,
    append_collection_error,
    fetch_latest_snapshots,
    init_db,
    iter_recent_snapshots,
    upsert_collection_run,
    upsert_collection_snapshot,
)
from src.quant_engine.data_collection_backend_v1 import CollectionStoreSpec, normalize_store_spec


def test_store_writes_and_reads_snapshots(tmp_path):
    db_path = tmp_path / "collector.db"
    init_db(db_path)
    upsert_collection_run(
        db_path,
        CollectionRun(
            run_id="run-1",
            collector_name="collector",
            started_at="2026-06-21T12:00:00+09:00",
            status="RUNNING",
            input_source="GatherTradingData.json",
            output_json_path="Temp/kis_data_collection_v1.json",
            output_db_path=str(db_path),
        ),
    )
    upsert_collection_snapshot(
        db_path,
        run_id="run-1",
        dataset_name="data_feed",
        ticker="005930",
        name="삼성전자",
        sector="반도체",
        as_of_date="2026-06-21",
        source_priority="kis_open_api>gathertradingdata_json",
        source_status="OK",
        payload={"ticker": "005930", "close": 1000},
        provenance={"kis": {"status": "OK"}},
    )
    append_collection_error(
        db_path,
        run_id="run-1",
        source_name="kis",
        error_kind="TimeoutError",
        error_message="timeout",
        ticker="005930",
    )

    conn = sqlite3.connect(db_path)
    try:
        run_count = conn.execute("SELECT COUNT(*) FROM collection_runs").fetchone()[0]
        snap_count = conn.execute("SELECT COUNT(*) FROM collection_snapshots").fetchone()[0]
        err_count = conn.execute("SELECT COUNT(*) FROM collection_source_errors").fetchone()[0]
    finally:
        conn.close()

    assert run_count == 1
    assert snap_count == 1
    assert err_count == 1
    assert fetch_latest_snapshots(db_path, "005930")[0]["dataset_name"] == "data_feed"
    assert len(list(iter_recent_snapshots(db_path, limit=5))) == 1


def test_store_overwrites_same_run_and_ticker(tmp_path):
    db_path = tmp_path / "collector.db"
    upsert_collection_snapshot(
        db_path,
        run_id="run-1",
        dataset_name="data_feed",
        ticker="005930",
        name="삼성전자",
        sector="반도체",
        as_of_date="2026-06-21",
        source_priority="kis_open_api",
        source_status="OK",
        payload={"ticker": "005930", "close": 1000},
        provenance={"source_priority": ["kis_open_api"]},
    )
    upsert_collection_snapshot(
        db_path,
        run_id="run-1",
        dataset_name="data_feed",
        ticker="005930",
        name="삼성전자",
        sector="반도체",
        as_of_date="2026-06-21",
        source_priority="kis_open_api>naver_finance",
        source_status="OK",
        payload={"ticker": "005930", "close": 2000},
        provenance={"source_priority": ["kis_open_api", "naver_finance"]},
    )
    rows = fetch_latest_snapshots(db_path, "005930")
    assert rows[0]["source_priority"] == "kis_open_api>naver_finance"


def test_store_backend_normalization_supports_sqlite_paths(tmp_path):
    backend, location = normalize_store_spec(CollectionStoreSpec(location=tmp_path / "collector.db"), ROOT)
    assert backend == "sqlite"
    assert str(location).endswith("collector.db")
