#!/usr/bin/env python3
"""
Test script to check available camera indices
"""

import cv2
import logging
import sys
import subprocess

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
)
logger = logging.getLogger("camera_index_test")

def test_camera_index(index):
    """Test if a camera index is available"""
    try:
        cap = cv2.VideoCapture(index)
        if cap.isOpened():
            ret, frame = cap.read()
            if ret and frame is not None:
                width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
                height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
                fps = cap.get(cv2.CAP_PROP_FPS)
                
                cap.release()
                return True, f"{width}x{height} @ {fps}fps"
            else:
                cap.release()
                return False, "Can open but cannot read frames"
        else:
            cap.release()
            return False, "Cannot open camera"
    except Exception as e:
        return False, f"Error: {str(e)}"

def get_windows_cameras_ffmpeg():
    """Get available cameras on Windows using FFmpeg"""
    try:
        result = subprocess.run(['ffmpeg', '-f', 'dshow', '-list_devices', 'true', '-i', 'dummy'], 
                              capture_output=True, text=True, timeout=10, encoding='utf-8', errors='ignore')
        output = result.stderr
        
        lines = output.split('\n')
        video_devices = []
        
        # Parse the output - look for lines with (video) that contain device names in quotes
        for line in lines:
            if '[dshow @' in line and '(video)' in line and '"' in line:
                # Extract device name between first pair of quotes
                start = line.find('"') + 1
                end = line.find('"', start)
                if start > 0 and end > start:
                    device_name = line[start:end]
                    video_devices.append(device_name)
        
        logger.info(f"FFmpeg detected video devices: {video_devices}")
        return video_devices
    except Exception as e:
        logger.error(f"Failed to get Windows camera names: {e}")
        return []

def main():
    logger.info("=== Camera Index Test ===")
    
    # Check FFmpeg availability for Windows device detection
    ffmpeg_available = False
    try:
        result = subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True, timeout=5)
        if result.returncode == 0:
            ffmpeg_available = True
            logger.info("FFmpeg is available")
    except:
        logger.info("FFmpeg not available")
    
    # Get Windows camera names if possible
    if sys.platform.startswith('win') and ffmpeg_available:
        logger.info("\n=== Windows Camera Devices (FFmpeg) ===")
        cameras = get_windows_cameras_ffmpeg()
        if cameras:
            for i, camera in enumerate(cameras):
                logger.info(f"Device {i}: {camera}")
        else:
            logger.info("No cameras detected via FFmpeg")
    
    # Test camera indices 0-9
    logger.info("\n=== Testing Camera Indices ===")
    available_cameras = []
    
    for index in range(10):
        logger.info(f"Testing camera index {index}...")
        is_available, info = test_camera_index(index)
        
        if is_available:
            logger.info(f"✓ Camera {index}: AVAILABLE - {info}")
            available_cameras.append(index)
        else:
            logger.info(f"✗ Camera {index}: NOT AVAILABLE - {info}")
    
    # Summary
    logger.info("\n=== Summary ===")
    if available_cameras:
        logger.info(f"Available camera indices: {available_cameras}")
        logger.info(f"Default camera index to use: {available_cameras[0]}")
        
        # Test the first available camera more thoroughly
        logger.info(f"\n=== Detailed Test for Camera {available_cameras[0]} ===")
        cap = cv2.VideoCapture(available_cameras[0])
        if cap.isOpened():
            # Get properties
            width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            fps = cap.get(cv2.CAP_PROP_FPS)
            backend = cap.getBackendName()
            
            logger.info(f"Resolution: {width}x{height}")
            logger.info(f"FPS: {fps}")
            logger.info(f"Backend: {backend}")
            
            # Test frame capture
            ret, frame = cap.read()
            if ret and frame is not None:
                logger.info(f"Frame capture: SUCCESS")
                logger.info(f"Frame shape: {frame.shape}")
                logger.info(f"Frame dtype: {frame.dtype}")
            else:
                logger.info(f"Frame capture: FAILED")
            
            cap.release()
    else:
        logger.error("No cameras available!")
        logger.info("Possible solutions:")
        logger.info("1. Check if camera is connected and not used by another application")
        logger.info("2. Check camera permissions")
        logger.info("3. Try different camera indices")
        logger.info("4. Install camera drivers")

if __name__ == "__main__":
    main()