#!/usr/bin/env python3
"""Test script for device flow authentication.

This script tests the browser-mediated completion flow by:
1. Starting device authorization
2. Simulating user providing completion code
3. Verifying tokens are obtained and stored

Run with:
    .venv/bin/python scripts/test_auth_flow.py
"""
import sys
sys.path.insert(0, "src")

from platform_2step_mcp.auth import AuthClient
from platform_2step_mcp.auth.storage import TokenStorage

BFF_URL = "http://localhost:8001"


def test_device_flow():
    """Test the device flow authentication."""
    print("=" * 60)
    print("Testing Device Flow Authentication")
    print("=" * 60)

    # Clear any existing tokens
    storage = TokenStorage()
    storage.clear()
    print("\n1. Cleared existing tokens")

    # Create auth client with custom completion code callback
    def get_completion_code():
        """Simulated completion code - in real use, this would be user input."""
        return "COMPLETE-test-mock-token"

    auth = AuthClient(
        bff_url=BFF_URL,
        completion_code_callback=get_completion_code,
    )

    try:
        # Start device auth to get user code
        print("\n2. Starting device authorization...")
        device_info = auth.start_device_auth()
        print(f"   Device code: {device_info.device_code[:20]}...")
        print(f"   User code: {device_info.user_code}")
        print(f"   Verification URI: {device_info.verification_uri}")

        # Exchange completion code for tokens
        print("\n3. Exchanging completion code for tokens...")
        tokens = auth.exchange_completion_code(
            device_code=device_info.device_code,
            completion_code="COMPLETE-test-mock-token",
        )
        print(f"   Access token: {tokens.access_token[:30]}...")
        print(f"   Refresh token: {tokens.refresh_token[:30] if tokens.refresh_token else 'None'}...")
        print(f"   Scope: {tokens.scope}")
        print(f"   Expires at: {tokens.expires_at}")

        # Verify tokens were stored
        print("\n4. Verifying token storage...")
        loaded = storage.load()
        if loaded:
            print(f"   Tokens successfully stored and loaded!")
            print(f"   Access token matches: {loaded.access_token == tokens.access_token}")
        else:
            print("   ERROR: Tokens not found in storage!")
            return False

        # Test token retrieval
        print("\n5. Testing get_valid_token()...")
        valid_token = auth.get_valid_token()
        print(f"   Got valid token: {valid_token[:30]}...")

        print("\n" + "=" * 60)
        print("SUCCESS: Device flow authentication works!")
        print("=" * 60)
        return True

    except Exception as e:
        print(f"\nERROR: {type(e).__name__}: {e}")
        import traceback
        traceback.print_exc()
        return False
    finally:
        auth.close()


def test_cached_tokens():
    """Test that cached tokens are used on subsequent calls."""
    print("\n" + "=" * 60)
    print("Testing Cached Token Reuse")
    print("=" * 60)

    def fail_if_called():
        raise RuntimeError("Should not prompt for completion code with cached tokens!")

    auth = AuthClient(
        bff_url=BFF_URL,
        completion_code_callback=fail_if_called,
    )

    try:
        print("\n1. Authenticating (should use cached tokens)...")
        tokens = auth.authenticate()
        print(f"   Got tokens from cache!")
        print(f"   Access token: {tokens.access_token[:30]}...")

        print("\n" + "=" * 60)
        print("SUCCESS: Cached tokens are reused!")
        print("=" * 60)
        return True
    except RuntimeError as e:
        print(f"\nERROR: {e}")
        return False
    finally:
        auth.close()


def test_token_refresh():
    """Test token refresh flow."""
    print("\n" + "=" * 60)
    print("Testing Token Refresh")
    print("=" * 60)

    storage = TokenStorage()
    tokens = storage.load()
    if not tokens or not tokens.refresh_token:
        print("No refresh token available, skipping...")
        return True

    auth = AuthClient(bff_url=BFF_URL)

    try:
        print("\n1. Refreshing token...")
        new_tokens = auth.refresh_token(tokens.refresh_token)
        print(f"   New access token: {new_tokens.access_token[:30]}...")
        print(f"   New refresh token: {new_tokens.refresh_token[:30] if new_tokens.refresh_token else 'None'}...")

        print("\n" + "=" * 60)
        print("SUCCESS: Token refresh works!")
        print("=" * 60)
        return True
    except Exception as e:
        print(f"\nERROR: {type(e).__name__}: {e}")
        return False
    finally:
        auth.close()


if __name__ == "__main__":
    print("\nMake sure mock BFF server is running on http://localhost:8001")
    print("Start with: .venv/bin/python scripts/mock_bff.py\n")

    results = []
    results.append(("Device Flow", test_device_flow()))
    results.append(("Cached Tokens", test_cached_tokens()))
    results.append(("Token Refresh", test_token_refresh()))

    print("\n" + "=" * 60)
    print("TEST SUMMARY")
    print("=" * 60)
    for name, passed in results:
        status = "PASS" if passed else "FAIL"
        print(f"  {name}: {status}")

    all_passed = all(p for _, p in results)
    sys.exit(0 if all_passed else 1)
