import click
import pytest

from l4d2web.app import create_app
from l4d2web.config import load_config


def test_load_config_uses_environment(monkeypatch) -> None:
    monkeypatch.setenv("DATABASE_URL", "sqlite:///env.db")
    monkeypatch.setenv("SECRET_KEY", "env-secret")
    monkeypatch.setenv("JOB_WORKER_THREADS", "2")

    config = load_config()

    assert config["DATABASE_URL"] == "sqlite:///env.db"
    assert config["SECRET_KEY"] == "env-secret"
    assert config["JOB_WORKER_THREADS"] == 2


def test_create_app_does_not_overwrite_database_url_env(tmp_path, monkeypatch) -> None:
    monkeypatch.setenv("DATABASE_URL", "sqlite:///env.db")
    db_url = f"sqlite:///{tmp_path/'app.db'}"

    create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})

    assert load_config()["DATABASE_URL"] == "sqlite:///env.db"


def test_create_app_raises_when_secret_key_missing(tmp_path, monkeypatch) -> None:
    db_url = f"sqlite:///{tmp_path/'nokey.db'}"
    monkeypatch.delenv("SECRET_KEY", raising=False)

    with pytest.raises(RuntimeError):
        create_app({"TESTING": False, "DATABASE_URL": db_url})


def test_create_app_raises_when_secret_key_is_dev(tmp_path, monkeypatch) -> None:
    db_url = f"sqlite:///{tmp_path/'devkey.db'}"
    monkeypatch.setenv("SECRET_KEY", "dev")

    with pytest.raises(RuntimeError):
        create_app({"TESTING": False, "DATABASE_URL": db_url})


def test_session_cookie_secure_in_production(tmp_path, monkeypatch) -> None:
    db_url = f"sqlite:///{tmp_path/'cookie.db'}"
    monkeypatch.setenv("DATABASE_URL", db_url)
    monkeypatch.setattr("l4d2web.app.recover_stale_jobs", lambda: None)
    monkeypatch.setattr("l4d2web.app.start_job_workers", lambda app: None)

    app = create_app({"TESTING": False, "DATABASE_URL": db_url, "SECRET_KEY": "real-secret"})

    assert app.config["SESSION_COOKIE_SECURE"] is True


def test_session_cookie_secure_env_override(tmp_path, monkeypatch) -> None:
    db_url = f"sqlite:///{tmp_path/'cookie-env.db'}"
    monkeypatch.setenv("DATABASE_URL", db_url)
    monkeypatch.setenv("SESSION_COOKIE_SECURE", "false")
    monkeypatch.setattr("l4d2web.app.recover_stale_jobs", lambda: None)
    monkeypatch.setattr("l4d2web.app.start_job_workers", lambda app: None)

    app = create_app({"TESTING": False, "DATABASE_URL": db_url, "SECRET_KEY": "real"})

    assert app.config["SESSION_COOKIE_SECURE"] is False


def test_session_cookie_secure_disabled_in_testing(tmp_path, monkeypatch) -> None:
    db_url = f"sqlite:///{tmp_path/'cookie-test.db'}"
    monkeypatch.setenv("DATABASE_URL", db_url)

    app = create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})

    assert app.config["SESSION_COOKIE_SECURE"] is False


def test_create_app_skips_job_workers_in_cli_context(tmp_path, monkeypatch) -> None:
    calls = []
    db_url = f"sqlite:///{tmp_path/'cli.db'}"
    monkeypatch.setenv("DATABASE_URL", db_url)
    monkeypatch.setattr("l4d2web.app.recover_stale_jobs", lambda: calls.append("recover"))
    monkeypatch.setattr("l4d2web.app.start_job_workers", lambda app: calls.append("start"))

    with click.Context(click.Command("flask")):
        create_app({"TESTING": False, "DATABASE_URL": db_url, "SECRET_KEY": "test"})

    assert calls == []
