"""
Redis Cache Tests - No pytest required
=======================================
Test Redis Cloud connection and caching functionality.
Run: python tests/test_redis.py
"""
import asyncio
import sys
import time

# Add parent dir to path
sys.path.insert(0, ".")

import redis.asyncio as aioredis

from config import (
    REDIS_CACHE_URL,
    REDIS_CACHE_PORT,
    REDIS_CACHE_DB,
    REDIS_PASSWORD,
    REDIS_USERNAME,
)


async def test_redis_ping():
    """Test basic Redis PING command."""
    print("1. Testing Redis PING...")
    client = aioredis.Redis(
        host=REDIS_CACHE_URL,
        port=REDIS_CACHE_PORT,
        db=REDIS_CACHE_DB,
        password=REDIS_PASSWORD,
        username=REDIS_USERNAME,
        decode_responses=True,
        socket_connect_timeout=10,
    )
    try:
        result = await client.ping()
        assert result is True, "Redis PING should return True"
        print("   ✅ Redis PING successful")
        return True
    except Exception as e:
        print(f"   ❌ PING failed: {e}")
        return False
    finally:
        await client.close()


async def test_redis_set_get():
    """Test Redis SET and GET operations."""
    print("2. Testing Redis SET/GET...")
    client = aioredis.Redis(
        host=REDIS_CACHE_URL,
        port=REDIS_CACHE_PORT,
        db=REDIS_CACHE_DB,
        password=REDIS_PASSWORD,
        username=REDIS_USERNAME,
        decode_responses=True,
        socket_connect_timeout=10,
    )
    try:
        test_key = "test:opennotion:connection"
        test_value = "hello_from_tests"
        
        await client.set(test_key, test_value, ex=60)
        result = await client.get(test_key)
        
        assert result == test_value, f"Expected '{test_value}', got '{result}'"
        await client.delete(test_key)
        
        print("   ✅ Redis SET/GET successful")
        return True
    except Exception as e:
        print(f"   ❌ SET/GET failed: {e}")
        return False
    finally:
        await client.close()


async def test_redis_ttl():
    """Test Redis TTL (Time To Live)."""
    print("3. Testing Redis TTL...")
    client = aioredis.Redis(
        host=REDIS_CACHE_URL,
        port=REDIS_CACHE_PORT,
        db=REDIS_CACHE_DB,
        password=REDIS_PASSWORD,
        username=REDIS_USERNAME,
        decode_responses=True,
        socket_connect_timeout=10,
    )
    try:
        test_key = "test:opennotion:ttl"
        await client.set(test_key, "ttl_test", ex=300)
        
        ttl = await client.ttl(test_key)
        assert ttl > 0, "TTL should be positive"
        
        await client.delete(test_key)
        print(f"   ✅ Redis TTL test passed (TTL={ttl}s)")
        return True
    except Exception as e:
        print(f"   ❌ TTL test failed: {e}")
        return False
    finally:
        await client.close()


async def test_bulk_operations():
    """Test bulk SET/GET operations."""
    print("4. Testing bulk operations (100 ops)...")
    client = aioredis.Redis(
        host=REDIS_CACHE_URL,
        port=REDIS_CACHE_PORT,
        db=REDIS_CACHE_DB,
        password=REDIS_PASSWORD,
        username=REDIS_USERNAME,
        decode_responses=True,
        socket_connect_timeout=10,
    )
    try:
        # Bulk SET
        start = time.time()
        for i in range(100):
            await client.set(f"test:bulk:{i}", f"value_{i}", ex=60)
        set_time = time.time() - start
        
        # Bulk GET
        start = time.time()
        for i in range(100):
            await client.get(f"test:bulk:{i}")
        get_time = time.time() - start
        
        # Cleanup
        for i in range(100):
            await client.delete(f"test:bulk:{i}")
        
        print(f"   ✅ Bulk SET: {set_time:.2f}s ({100/set_time:.0f} ops/s)")
        print(f"   ✅ Bulk GET: {get_time:.2f}s ({100/get_time:.0f} ops/s)")
        return True
    except Exception as e:
        print(f"   ❌ Bulk test failed: {e}")
        return False
    finally:
        await client.close()


async def test_cache_module():
    """Test the RedisClient from common.cache."""
    print("5. Testing cache module...")
    try:
        from common.cache import redis_cache
        
        client = await redis_cache.connect()
        if client:
            print("   ✅ Cache module connected successfully")
            stats = redis_cache.get_stats()
            print(f"   📊 Cache stats: {stats}")
            return True
        else:
            print("   ⚠️  Cache module disabled (no connection)")
            return True
    except Exception as e:
        print(f"   ❌ Cache module failed: {e}")
        return False


async def run_all_tests():
    """Run all Redis tests."""
    print("\n" + "="*60)
    print("🔴 REDIS CONNECTION TESTS")
    print(f"   Host: {REDIS_CACHE_URL}")
    print(f"   Port: {REDIS_CACHE_PORT}")
    print("="*60 + "\n")
    
    results = []
    
    results.append(await test_redis_ping())
    results.append(await test_redis_set_get())
    results.append(await test_redis_ttl())
    results.append(await test_bulk_operations())
    results.append(await test_cache_module())
    
    print("\n" + "="*60)
    passed = sum(results)
    total = len(results)
    
    if passed == total:
        print(f"✅ ALL TESTS PASSED! ({passed}/{total})")
    else:
        print(f"⚠️  {passed}/{total} tests passed")
    print("="*60 + "\n")


if __name__ == "__main__":
    asyncio.run(run_all_tests())
