#!/usr/bin/env python3
"""
Backend test for push_enabled server kill-switch feature.
Tests the new push_enabled flag in settings and app-info endpoint.
"""
import requests
import json
import sys

# Use localhost for direct testing as per review request
BASE_URL = "http://localhost:8001"
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "admin123"

def print_test(name):
    print(f"\n{'='*70}")
    print(f"TEST: {name}")
    print('='*70)

def print_pass(msg):
    print(f"✅ PASS: {msg}")

def print_fail(msg):
    print(f"❌ FAIL: {msg}")
    
def print_info(msg):
    print(f"ℹ️  INFO: {msg}")

def test_1_app_info_initial():
    """Test 1: GET /api/public/app-info (public, no auth) - check flags.push_enabled defaults to false"""
    print_test("1. GET /api/public/app-info - verify flags.push_enabled defaults to false")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/app-info", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        print_info(f"Response keys: {list(data.keys())}")
        
        # Check if flags key exists
        if 'flags' not in data:
            print_fail("'flags' key not found in response")
            return False
        print_pass("'flags' key present in response")
        
        flags = data['flags']
        print_info(f"Flags: {json.dumps(flags, indent=2)}")
        
        # Check if push_enabled exists in flags
        if 'push_enabled' not in flags:
            print_fail("'push_enabled' not found in flags")
            return False
        print_pass("'push_enabled' field present in flags")
        
        # Check if push_enabled defaults to false
        if flags['push_enabled'] != False:
            print_fail(f"Expected push_enabled=false, got push_enabled={flags['push_enabled']}")
            return False
        print_pass(f"push_enabled correctly defaults to false")
        
        print_pass("✅ Test 1 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_2_admin_login():
    """Test 2: POST /api/auth/login with admin/admin123 → capture JWT"""
    print_test("2. POST /api/auth/login - admin login")
    
    try:
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
            timeout=10
        )
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return None
        
        data = response.json()
        
        if 'access_token' not in data:
            print_fail("No access_token in response")
            print_info(f"Response: {json.dumps(data, indent=2)}")
            return None
        
        token = data['access_token']
        print_pass(f"Login successful, got JWT token: {token[:30]}...")
        print_pass("✅ Test 2 PASSED")
        return token
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return None

def test_3_get_admin_settings(token):
    """Test 3: GET /api/admin/settings (bearer) - confirm push_enabled field exists and is false"""
    print_test("3. GET /api/admin/settings - verify push_enabled field")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        response = requests.get(f"{BASE_URL}/api/admin/settings", headers=headers, timeout=10)
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        print_info(f"Response has {len(data)} keys")
        
        # Check if push_enabled field exists
        if 'push_enabled' not in data:
            print_fail("push_enabled field not found in settings")
            print_info(f"Available keys: {list(data.keys())}")
            return False
        
        print_pass(f"push_enabled field present in settings")
        
        # Check value is false
        if data['push_enabled'] != False:
            print_fail(f"Expected push_enabled=false, got push_enabled={data['push_enabled']}")
            return False
        print_pass(f"push_enabled value is false: {data['push_enabled']}")
        
        print_pass("✅ Test 3 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_4_enable_push(token):
    """Test 4: PUT /api/admin/settings with {"push_enabled": true} → must return 200 and persist"""
    print_test("4. PUT /api/admin/settings - set push_enabled to true")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        payload = {"push_enabled": True}
        
        print_info(f"Payload: {json.dumps(payload, indent=2)}")
        
        response = requests.put(
            f"{BASE_URL}/api/admin/settings",
            headers=headers,
            json=payload,
            timeout=10
        )
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        
        # Verify the update persisted
        if data.get('push_enabled') != True:
            print_fail(f"push_enabled not updated. Expected: True, Got: {data.get('push_enabled')}")
            return False
        print_pass(f"push_enabled successfully updated to: {data['push_enabled']}")
        
        print_pass("✅ Test 4 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_5_verify_app_info_push_enabled():
    """Test 5: Re-GET /api/public/app-info → flags.push_enabled MUST now be true"""
    print_test("5. GET /api/public/app-info - verify flags.push_enabled is now true")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/app-info", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        
        # Check flags.push_enabled is true
        if 'flags' not in data:
            print_fail("'flags' key not found in response")
            return False
        
        flags = data['flags']
        
        if 'push_enabled' not in flags:
            print_fail("'push_enabled' not found in flags")
            return False
        
        if flags['push_enabled'] != True:
            print_fail(f"Expected push_enabled=true, got push_enabled={flags['push_enabled']}")
            return False
        print_pass(f"flags.push_enabled correctly updated to true")
        
        print_pass("✅ Test 5 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_6_disable_push(token):
    """Test 6: PUT /api/admin/settings with {"push_enabled": false} → confirm it goes back to false"""
    print_test("6. PUT /api/admin/settings - set push_enabled back to false")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        payload = {"push_enabled": False}
        
        print_info(f"Payload: {json.dumps(payload, indent=2)}")
        
        response = requests.put(
            f"{BASE_URL}/api/admin/settings",
            headers=headers,
            json=payload,
            timeout=10
        )
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        
        # Verify the update persisted
        if data.get('push_enabled') != False:
            print_fail(f"push_enabled not updated. Expected: False, Got: {data.get('push_enabled')}")
            return False
        print_pass(f"push_enabled successfully reset to: {data['push_enabled']}")
        
        print_pass("✅ Test 6 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_7_verify_app_info_push_disabled():
    """Test 7: Re-GET /api/public/app-info → flags.push_enabled MUST be false again"""
    print_test("7. GET /api/public/app-info - verify flags.push_enabled is false again")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/app-info", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        
        # Check flags.push_enabled is false
        if 'flags' not in data:
            print_fail("'flags' key not found in response")
            return False
        
        flags = data['flags']
        
        if 'push_enabled' not in flags:
            print_fail("'push_enabled' not found in flags")
            return False
        
        if flags['push_enabled'] != False:
            print_fail(f"Expected push_enabled=false, got push_enabled={flags['push_enabled']}")
            return False
        print_pass(f"flags.push_enabled correctly reset to false")
        
        print_pass("✅ Test 7 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def test_8_regression_ad_config():
    """Test 8: Regression - confirm GET /api/public/ad-config still returns rewarded_id field"""
    print_test("8. REGRESSION - GET /api/public/ad-config - verify rewarded_id field")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/ad-config", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        print_info(f"Response keys: {list(data.keys())}")
        
        # Check if rewarded_id field exists
        if 'rewarded_id' not in data:
            print_fail("rewarded_id field not found in ad-config (REGRESSION)")
            return False
        print_pass(f"rewarded_id field present: {data['rewarded_id']}")
        
        print_pass("✅ Test 8 PASSED - No regression")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        import traceback
        traceback.print_exc()
        return False

def main():
    print("\n" + "="*70)
    print("NADIPLAYER BACKEND TEST - PUSH_ENABLED KILL-SWITCH")
    print("="*70)
    print(f"Testing against: {BASE_URL}")
    print(f"Admin credentials: {ADMIN_USERNAME} / {ADMIN_PASSWORD}")
    
    results = {}
    
    # Test 1: Initial app-info check - push_enabled defaults to false
    results['test_1_app_info_initial'] = test_1_app_info_initial()
    
    # Test 2: Admin login
    token = test_2_admin_login()
    results['test_2_admin_login'] = token is not None
    
    if token:
        # Test 3: Get admin settings - verify push_enabled field exists
        results['test_3_get_settings'] = test_3_get_admin_settings(token)
        
        # Test 4: Enable push_enabled
        results['test_4_enable_push'] = test_4_enable_push(token)
        
        # Test 5: Verify app-info reflects push_enabled=true
        results['test_5_verify_enabled'] = test_5_verify_app_info_push_enabled()
        
        # Test 6: Disable push_enabled (leave system safe)
        results['test_6_disable_push'] = test_6_disable_push(token)
        
        # Test 7: Verify app-info reflects push_enabled=false
        results['test_7_verify_disabled'] = test_7_verify_app_info_push_disabled()
    else:
        results['test_3_get_settings'] = False
        results['test_4_enable_push'] = False
        results['test_5_verify_enabled'] = False
        results['test_6_disable_push'] = False
        results['test_7_verify_disabled'] = False
    
    # Test 8: Regression check - ad-config still has rewarded_id
    results['test_8_regression'] = test_8_regression_ad_config()
    
    # Summary
    print("\n" + "="*70)
    print("TEST SUMMARY")
    print("="*70)
    
    passed = sum(1 for v in results.values() if v)
    total = len(results)
    
    for test_name, result in results.items():
        status = "✅ PASS" if result else "❌ FAIL"
        print(f"{test_name}: {status}")
    
    print(f"\nTotal: {passed}/{total} tests passed")
    
    if passed == total:
        print("\n🎉 ALL TESTS PASSED!")
        print("\nSUMMARY:")
        print("- push_enabled field correctly added to settings model")
        print("- push_enabled defaults to false (safe default)")
        print("- Admin can toggle push_enabled via PUT /api/admin/settings")
        print("- Changes persist and are reflected in /api/public/app-info")
        print("- No regression: ad-config still returns rewarded_id field")
        return 0
    else:
        print(f"\n⚠️  {total - passed} test(s) failed")
        return 1

if __name__ == "__main__":
    sys.exit(main())
