from pathlib import Path

from l4d2web.app import create_app
from l4d2web.db import init_db, session_scope
from l4d2web.models import Overlay


def _make_app(tmp_path: Path, monkeypatch):
    db_url = f"sqlite:///{tmp_path/'seed.db'}"
    monkeypatch.setenv("DATABASE_URL", db_url)
    monkeypatch.setenv("LEFT4ME_ROOT", str(tmp_path))
    app = create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})
    init_db()
    return app


def test_seed_creates_system_wide_script_overlays(tmp_path: Path, monkeypatch) -> None:
    app = _make_app(tmp_path, monkeypatch)
    examples = tmp_path / "examples"
    examples.mkdir()
    (examples / "alpha.sh").write_text("#!/bin/bash\necho alpha\n")
    (examples / "beta.sh").write_text("#!/bin/bash\necho beta\n")

    result = app.test_cli_runner().invoke(args=["seed-script-overlays", str(examples)])

    assert result.exit_code == 0, result.output
    with session_scope() as db:
        rows = db.query(Overlay).order_by(Overlay.name).all()
        assert [(o.name, o.type, o.user_id, o.script.strip()) for o in rows] == [
            ("alpha", "script", None, "#!/bin/bash\necho alpha"),
            ("beta", "script", None, "#!/bin/bash\necho beta"),
        ]
        for o in rows:
            assert (tmp_path / "overlays" / o.path).is_dir()


def test_seed_refreshes_existing_script_overlay(tmp_path: Path, monkeypatch) -> None:
    app = _make_app(tmp_path, monkeypatch)
    examples = tmp_path / "examples"
    examples.mkdir()
    (examples / "alpha.sh").write_text("v1\n")

    runner = app.test_cli_runner()
    runner.invoke(args=["seed-script-overlays", str(examples)])
    (examples / "alpha.sh").write_text("v2\n")
    result = runner.invoke(args=["seed-script-overlays", str(examples)])

    assert result.exit_code == 0, result.output
    with session_scope() as db:
        rows = db.query(Overlay).filter(Overlay.name == "alpha").all()
        assert len(rows) == 1
        assert rows[0].script.strip() == "v2"


def test_seed_errors_on_type_collision(tmp_path: Path, monkeypatch) -> None:
    app = _make_app(tmp_path, monkeypatch)
    examples = tmp_path / "examples"
    examples.mkdir()
    (examples / "shared.sh").write_text("#!/bin/bash\n")

    with session_scope() as db:
        db.add(Overlay(name="shared", path="shared", type="workshop", user_id=None))

    result = app.test_cli_runner().invoke(args=["seed-script-overlays", str(examples)])

    assert result.exit_code != 0
    assert "not script" in result.output


def test_seed_no_files_is_noop(tmp_path: Path, monkeypatch) -> None:
    app = _make_app(tmp_path, monkeypatch)
    examples = tmp_path / "examples"
    examples.mkdir()

    result = app.test_cli_runner().invoke(args=["seed-script-overlays", str(examples)])

    assert result.exit_code == 0
    with session_scope() as db:
        assert db.query(Overlay).count() == 0
