"""End-to-end integration tests for the deployed-environment E2E
test-auth path (`POST /auth/test/login`).

This endpoint is a **deliberately gated auth shortcut** for running the
Playwright E2E suite against a *deployed* environment (PPE) that has no
Mailpit OTC sink and no direct SQLite access to inject an owner row —
the two scaffolds the Tier-1 stack relies on. It mints an authenticated
**owner** session for a single, pre-configured test identity, but ONLY
when the deployment has explicitly opted in by setting BOTH
`E2E_TEST_AUTH_SECRET` and `E2E_TEST_AUTH_EMAIL`. It is fail-closed:

  * Off by default — with neither (or only one) env var set, the route
    is invisible (404), so a production deployment that never sets them
    cannot be coaxed into minting a session.
  * Even when enabled, it requires the caller to present the shared
    secret in the `X-Test-Auth-Secret` header (constant-time compare),
    and it will only mint a session for the one configured email — any
    other address is refused (403). So the blast radius of an enabled
    PPE is a single throwaway owner identity, and the secret is the
    trust boundary.

The tests below pin every branch of that gate.
"""
from __future__ import annotations

from test_propose_vertical import (  # noqa: F401
    FakeGitea,
    app_with_fake_gitea,
    tmp_env,
)

SECRET = "ppe-e2e-shared-secret-value"
EMAIL = "e2e-owner@example.test"


def test_test_login_is_404_when_disabled(app_with_fake_gitea):
    """Neither env var set (the default, incl. production) → the route
    does not exist."""
    from fastapi.testclient import TestClient

    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 404, r.text


def test_test_login_is_404_when_only_email_is_set(app_with_fake_gitea, monkeypatch):
    """Half-configured (email but no secret) must NOT open the route —
    a framework auth shortcut gated only by a known email would be far
    too weak."""
    from fastapi.testclient import TestClient

    monkeypatch.setenv("E2E_TEST_AUTH_EMAIL", EMAIL)
    monkeypatch.delenv("E2E_TEST_AUTH_SECRET", raising=False)
    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 404, r.text


def test_test_login_refuses_wrong_secret(app_with_fake_gitea, monkeypatch):
    """Enabled, but a bad/absent secret → 404 (don't advertise the
    route's existence to an unauthenticated caller)."""
    from fastapi.testclient import TestClient

    monkeypatch.setenv("E2E_TEST_AUTH_SECRET", SECRET)
    monkeypatch.setenv("E2E_TEST_AUTH_EMAIL", EMAIL)
    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        # Wrong secret.
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL},
            headers={"X-Test-Auth-Secret": "not-the-secret"},
        )
        assert r.status_code == 404, r.text
        # Absent secret.
        r = client.post("/auth/test/login", json={"email": EMAIL})
        assert r.status_code == 404, r.text


def test_test_login_refuses_unconfigured_email(app_with_fake_gitea, monkeypatch):
    """Right secret but an email other than the single configured
    identity → 403. Even a secret-bearer can only mint the one test
    owner."""
    from fastapi.testclient import TestClient

    monkeypatch.setenv("E2E_TEST_AUTH_SECRET", SECRET)
    monkeypatch.setenv("E2E_TEST_AUTH_EMAIL", EMAIL)
    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        r = client.post(
            "/auth/test/login",
            json={"email": "someone-else@example.test"},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 403, r.text


def test_test_login_mints_owner_session(app_with_fake_gitea, monkeypatch):
    """The happy path: right secret + configured email → an authenticated
    session whose user is a GRANTED OWNER (so the metadata write paths —
    SLICE-4 edit, SLICE-5 bulk — accept it), persisted on a fresh
    `users` row."""
    from fastapi.testclient import TestClient

    monkeypatch.setenv("E2E_TEST_AUTH_SECRET", SECRET)
    monkeypatch.setenv("E2E_TEST_AUTH_EMAIL", EMAIL)
    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 200, r.text

        # The session cookie now surfaces an authenticated owner.
        me = client.get("/api/auth/me").json()
        assert me["authenticated"] is True
        assert me["user"]["email"] == EMAIL
        assert me["user"]["role"] == "owner"
        assert me["user"]["permission_state"] == "granted"

        # Idempotent: a second login reuses the same row (still owner).
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 200, r.text

        from app import db
        rows = db.conn().execute(
            "SELECT role, permission_state FROM users WHERE email = ? COLLATE NOCASE",
            (EMAIL,),
        ).fetchall()
        assert len(rows) == 1
        assert rows[0]["role"] == "owner"
        assert rows[0]["permission_state"] == "granted"


def test_test_login_is_case_insensitive_on_email(app_with_fake_gitea, monkeypatch):
    """The configured-email check matches case-insensitively, mirroring
    how the rest of the auth stack treats email."""
    from fastapi.testclient import TestClient

    monkeypatch.setenv("E2E_TEST_AUTH_SECRET", SECRET)
    monkeypatch.setenv("E2E_TEST_AUTH_EMAIL", EMAIL)
    app, _fake = app_with_fake_gitea
    with TestClient(app) as client:
        r = client.post(
            "/auth/test/login",
            json={"email": EMAIL.upper()},
            headers={"X-Test-Auth-Secret": SECRET},
        )
        assert r.status_code == 200, r.text
