"""
Tests for Story 6.6: Environment configuration and fail-fast validation (NFR10).
- With ENV=development (or unset): no fail-fast, validate_required_env returns [].
- With ENV=production and missing required vars: validate_required_env returns list of missing names.
- Startup exit message format (tested via validation output; full main import may lack deps in test env).
"""

import os
import sys
import subprocess
import tempfile

# Project root for cwd and PYTHONPATH
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


def test_validate_required_env_development_returns_empty():
    """In development, no required vars are enforced (defaults/warnings allowed)."""
    env = os.environ.copy()
    env.pop("ENV", None)
    env.pop("ENVIRONMENT", None)
    env["ENV"] = "development"
    result = subprocess.run(
        [sys.executable, "-c", "from config import config; print(repr(config.validate_required_env()))"],
        capture_output=True,
        text=True,
        cwd=ROOT,
        env=env,
    )
    assert result.returncode == 0
    out = (result.stdout or "").strip()
    assert out == "[]", f"Expected [] in development, got {out}"


def test_validate_required_env_production_reports_missing():
    """In production with no .env loaded, all required vars are reported missing."""
    with tempfile.TemporaryDirectory() as tmp:
        env = {
            "ENV": "production",
            "PATH": os.environ.get("PATH", ""),
            "PYTHONPATH": ROOT,
        }
        # Run from empty dir so load_dotenv() does not load project .env
        result = subprocess.run(
            [
                sys.executable,
                "-c",
                "from config import config; m = config.validate_required_env(); print(','.join(sorted(m)))",
            ],
            capture_output=True,
            text=True,
            cwd=tmp,
            env=env,
        )
    assert result.returncode == 0
    out = (result.stdout or "").strip()
    required_names = {"ADMIN_PASSWORD or ADMIN_PASSWORD_HASH", "ADMIN_TOKEN_SECRET", "ADMIN_USERNAME", "DATABASE_URL", "JWT_SECRET_KEY", "REDIS_URL"}
    reported = set(out.split(",")) if out else set()
    assert required_names == reported, f"Expected {required_names}, got {reported}"


def test_fail_fast_message_lists_vars_and_env_example():
    """With ENV=production and some vars missing, message lists them and mentions .env.example."""
    with tempfile.TemporaryDirectory() as tmp:
        env = {"ENV": "production", "PATH": os.environ.get("PATH", ""), "PYTHONPATH": ROOT}
        result = subprocess.run(
            [
                sys.executable,
                "-c",
                "from config import config; m = config.validate_required_env(); "
                "msg = 'Missing required env: ' + ', '.join(m) + '. Set them in .env or environment. See .env.example.' if m else ''; "
                "print(msg)",
            ],
            capture_output=True,
            text=True,
            cwd=tmp,
            env=env,
        )
    assert result.returncode == 0
    out = (result.stdout or "").strip()
    assert "Missing required env" in out
    assert ".env.example" in out
    assert "JWT_SECRET_KEY" in out or "DATABASE_URL" in out or "REDIS_URL" in out


def test_validate_required_env_production_postgres_star_satisfies_database_url():
    """When POSTGRES_* are set (and DATABASE_URL is not), DATABASE_URL is not reported missing (AC #1)."""
    with tempfile.TemporaryDirectory() as tmp:
        env = {
            "ENV": "production",
            "PATH": os.environ.get("PATH", ""),
            "PYTHONPATH": ROOT,
            "POSTGRES_HOST": "localhost",
            "POSTGRES_PORT": "5432",
            "POSTGRES_USER": "u",
            "POSTGRES_PASSWORD": "p",
            "POSTGRES_DB": "db",
            "JWT_SECRET_KEY": "x",
            "ADMIN_USERNAME": "a",
            "ADMIN_PASSWORD": "b",
            "ADMIN_TOKEN_SECRET": "c",
            "RATE_LIMIT_ENABLED": "false",
        }
        result = subprocess.run(
            [
                sys.executable,
                "-c",
                "from config import config; m = config.validate_required_env(); print(','.join(sorted(m)))",
            ],
            capture_output=True,
            text=True,
            cwd=tmp,
            env=env,
        )
    assert result.returncode == 0
    out = (result.stdout or "").strip()
    assert out == "", f"Expected no missing vars when POSTGRES_* set, got {out}"


def test_startup_exits_with_code_1_when_production_missing_required_env():
    """App startup must exit with code 1 when ENV=production and required vars are missing (Story 6.6)."""
    with tempfile.TemporaryDirectory() as tmp:
        env = {
            "ENV": "production",
            "PATH": os.environ.get("PATH", ""),
            "PYTHONPATH": ROOT,
        }
        result = subprocess.run(
            [sys.executable, "-c", "import main"],
            capture_output=True,
            text=True,
            cwd=tmp,
            env=env,
        )
    assert result.returncode == 1, f"Expected exit 1, got {result.returncode}. stderr: {result.stderr}"
    assert "Missing required env" in (result.stderr or "")
    assert ".env.example" in (result.stderr or "")
