"""Tests for the refresh subcommand."""

from __future__ import annotations

from pathlib import Path
from unittest.mock import patch

import duckdb
import pytest

from suivi_seo.refresh import run


def _bootstrap_minimal_db(db_path: Path) -> None:
    """Create just the `sites` table so init-db.sql can re-attach idempotently."""
    con = duckdb.connect(str(db_path))
    # init-db.sql uses CREATE TABLE IF NOT EXISTS everywhere, so an empty DB is fine.
    con.close()


def test_refresh_skips_when_evidence_dir_missing(
    tmp_path: Path, capsys: pytest.CaptureFixture
) -> None:
    """No --evidence-dir, no sibling evidence/ → skip npm run sources gracefully."""
    db_path = tmp_path / "test.duckdb"
    _bootstrap_minimal_db(db_path)

    # Patch sub-imports to avoid the (slow) heavy SQL runs; init-db.sql is fine on empty DB.
    # We patch `load_sql` to no-op all imports except init-db.sql.
    with patch("subprocess.run") as mock_run:
        # Use --site=acieb to skip eleva imports (no src DB); we will also stub load_sql.
        with patch("suivi_seo.refresh.load_sql", return_value="SELECT 1;"):
            rc = run(site="all", db_path=db_path, evidence_dir=None)

    assert rc == 0
    mock_run.assert_not_called()
    captured = capsys.readouterr()
    assert "Skipping Evidence cache rebuild" in captured.err


def test_refresh_calls_npm_with_correct_cwd(tmp_path: Path) -> None:
    """`--evidence-dir` provided and existing → subprocess.run(npm, cwd=...) called once."""
    db_path = tmp_path / "test.duckdb"
    _bootstrap_minimal_db(db_path)
    evidence_dir = tmp_path / "evidence"
    evidence_dir.mkdir()

    with (
        patch("subprocess.run") as mock_run,
        patch("suivi_seo.refresh.load_sql", return_value="SELECT 1;"),
    ):
        rc = run(site="eleva", db_path=db_path, evidence_dir=evidence_dir)

    assert rc == 0
    mock_run.assert_called_once()
    call_args, call_kwargs = mock_run.call_args
    assert call_args[0] == ["npm", "run", "sources"]
    assert call_kwargs["cwd"] == str(evidence_dir)
    assert call_kwargs.get("check") is True


def test_refresh_warns_when_evidence_dir_does_not_exist(
    tmp_path: Path, capsys: pytest.CaptureFixture
) -> None:
    """A non-existent --evidence-dir should not crash; just warn and skip."""
    db_path = tmp_path / "test.duckdb"
    _bootstrap_minimal_db(db_path)
    bogus = tmp_path / "does-not-exist"

    with (
        patch("subprocess.run") as mock_run,
        patch("suivi_seo.refresh.load_sql", return_value="SELECT 1;"),
    ):
        rc = run(site="acieb", db_path=db_path, evidence_dir=bogus)

    assert rc == 0
    mock_run.assert_not_called()
    captured = capsys.readouterr()
    assert "does not exist" in captured.err


def test_refresh_rejects_invalid_site(tmp_path: Path, capsys: pytest.CaptureFixture) -> None:
    """Calling run() directly with an unknown site must return non-zero."""
    db_path = tmp_path / "test.duckdb"
    _bootstrap_minimal_db(db_path)
    rc = run(site="bogus", db_path=db_path, evidence_dir=None)
    assert rc == 2
    assert "must be one of" in capsys.readouterr().err
