"""Verify the / route serves marketing.landing for anonymous users
instead of redirecting them to /login (Task B-1.3).

Before B-1.3, recordings_bp.index was decorated with @login_required and
redirected anonymous users to /login. After B-1.3, anonymous users land
on the public marketing site; only authenticated users see the legacy
Speakr dashboard.

Implementation note: recordings.index calls marketing.routes.landing()
directly (not via redirect) because both endpoints are mounted at "/".
A redirect to url_for('marketing.landing') would resolve back to
recordings.index (registered first in the URL map) and cause an infinite
redirect loop. The expected behavior is therefore a direct 200 render,
NOT a redirect.

Pattern: no conftest.py, env vars set at module load time, then import
src.app.app directly. Mirrors tests/test_blueprint_registration.py.
"""

import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

os.environ.setdefault('SQLALCHEMY_DATABASE_URI', 'sqlite:///:memory:')
os.environ.setdefault('SECRET_KEY', 'test-secret-key-for-marketing-root-redirect')

from src.app import app  # noqa: E402


def test_anonymous_user_no_login_redirect():
    """Anonymous user GET / must NOT redirect to /login."""
    client = app.test_client()
    response = client.get('/', follow_redirects=False)
    if response.status_code in (301, 302, 303, 307, 308):
        location = response.headers.get('Location', '')
        assert '/login' not in location, (
            f"Expected no /login redirect, got: {location}"
        )


def test_anonymous_user_at_root_sees_marketing():
    """Anonymous user GET / receives marketing landing directly (no redirect).

    The handler must invoke the marketing.landing view function directly
    rather than redirecting, because url_for('marketing.landing') resolves
    back to '/' and would loop into recordings.index forever.
    """
    client = app.test_client()
    response = client.get('/', follow_redirects=False)
    # Direct render -- must be 200, NOT a redirect
    assert response.status_code == 200, (
        f"Expected 200 at / for anonymous (direct render, no redirect "
        f"to avoid loop), got {response.status_code}"
    )
    # Verify it's the marketing placeholder content
    body_lower = response.data.lower()
    assert (b'dictia' in body_lower) or (b'marketing' in body_lower), (
        f"Expected marketing content at /, got: {response.data[:200]!r}"
    )


def test_root_route_no_redirect_loop():
    """GET / must not bounce through redirects.

    Following redirects should reach a final 200 in <=1 hops; if Flask
    returns >1 redirect chain at /, it indicates the recordings.index
    handler is redirecting back to itself via url_for('marketing.landing').
    """
    client = app.test_client()
    response = client.get('/', follow_redirects=False)
    # Either an immediate 200 (preferred) or at most one redirect.
    assert response.status_code not in (301, 302, 303, 307, 308) or (
        '/login' not in response.headers.get('Location', '')
        and response.headers.get('Location', '') != '/'
    ), (
        f"Detected potential redirect loop at /: status="
        f"{response.status_code}, Location="
        f"{response.headers.get('Location', '')}"
    )


def test_root_route_resolves_to_recordings_index():
    """The recordings.index handler must still own '/' in the URL map.

    The collision between recordings.index and marketing.landing is
    deliberate: recordings.index is registered first and intercepts the
    request, then dispatches anonymous users to the marketing.landing
    view function directly (no URL-level redirect). This test pins that
    contract so a future refactor can't silently swap the registration
    order.
    """
    rules_for_root = [
        r for r in app.url_map.iter_rules() if str(r) == '/'
    ]
    endpoints = {r.endpoint for r in rules_for_root}
    # Both endpoints must exist; recordings.index is the active one.
    assert 'recordings.index' in endpoints, (
        f"Expected recordings.index to own '/', got endpoints: {endpoints}"
    )
    assert 'marketing.landing' in endpoints, (
        f"Expected marketing.landing also at '/', got endpoints: {endpoints}"
    )


def test_index_handler_no_longer_login_required():
    """recordings.index must not have @login_required after B-1.3.

    We assert this by hitting '/' anonymously and confirming the response
    is NOT a Flask-Login redirect to /login. (Flask-Login emits a
    302 with a `next` query parameter pointing back to '/'.)
    """
    client = app.test_client()
    response = client.get('/', follow_redirects=False)
    if response.status_code in (301, 302, 303, 307, 308):
        location = response.headers.get('Location', '')
        assert 'next=' not in location, (
            f"Detected Flask-Login redirect at /: {location} -- "
            "@login_required appears to still be on recordings.index"
        )
