#!/usr/bin/env python3
"""
M3U Playlist URL Validator
Tests video URLs with retry logic and timeout handling similar to VLC player
"""

import sys
import urllib.request
import urllib.error
import socket
from typing import List, Tuple

def test_url(url: str, timeout: int = 10, max_retries: int = 3) -> bool:
    """
    Test if a video URL is accessible by attempting to read the first 1KB.
    Uses retry logic and follows redirects similar to VLC player.

    Args:
        url: The video URL to test
        timeout: Connection timeout in seconds
        max_retries: Maximum number of retry attempts

    Returns:
        True if URL is accessible, False otherwise
    """
    for attempt in range(max_retries):
        try:
            # Create request with headers similar to VLC
            req = urllib.request.Request(url)
            req.add_header('User-Agent', 'VLCPlayer/3.0')
            req.add_header('Range', 'bytes=0-1023')  # Request first 1KB only

            # Attempt to open URL with timeout
            with urllib.request.urlopen(req, timeout=timeout) as response:
                # Try to read first 1KB
                data = response.read(1024)

                # If we got data, URL is valid
                if len(data) > 0:
                    return True

        except urllib.error.HTTPError as e:
            # HTTP 520 or other server errors - retry
            if attempt < max_retries - 1:
                continue
            return False

        except urllib.error.URLError as e:
            # Network error - retry
            if attempt < max_retries - 1:
                continue
            return False

        except socket.timeout:
            # Timeout - retry
            if attempt < max_retries - 1:
                continue
            return False

        except Exception as e:
            # Other errors - retry
            if attempt < max_retries - 1:
                continue
            return False

    return False


def parse_m3u(filepath: str) -> List[Tuple[str, str]]:
    """
    Parse M3U playlist file and extract entries with their URLs.

    Args:
        filepath: Path to M3U file

    Returns:
        List of tuples containing (entry_info, url)
    """
    entries = []
    current_info = None

    with open(filepath, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()

            if line.startswith('#EXTINF:'):
                current_info = line
            elif line and not line.startswith('#'):
                # This is a URL line
                if current_info:
                    entries.append((current_info, line))
                    current_info = None

    return entries


def validate_playlist(input_file: str, output_file: str = None, verbose: bool = True):
    """
    Validate all URLs in an M3U playlist and optionally create filtered version.

    Args:
        input_file: Path to input M3U file
        output_file: Path to output filtered M3U file (optional)
        verbose: Print validation progress
    """
    print(f"📋 Reading playlist: {input_file}")
    entries = parse_m3u(input_file)
    print(f"📊 Found {len(entries)} entries to validate\n")

    valid_entries = []
    invalid_entries = []

    for i, (info, url) in enumerate(entries, 1):
        # Extract name from info line
        name = "Unknown"
        if 'tvg-name="' in info:
            start = info.index('tvg-name="') + 10
            end = info.index('"', start)
            name = info[start:end]

        if verbose:
            print(f"[{i}/{len(entries)}] Testing: {name}")
            print(f"    URL: {url}")

        # Test URL
        is_valid = test_url(url)

        if is_valid:
            if verbose:
                print(f"    ✅ VALID\n")
            valid_entries.append((info, url))
        else:
            if verbose:
                print(f"    ❌ INVALID\n")
            invalid_entries.append((info, url))

    # Print summary
    print("=" * 70)
    print(f"📊 Validation Summary:")
    print(f"    Total entries: {len(entries)}")
    print(f"    Valid entries: {len(valid_entries)} ({len(valid_entries)/len(entries)*100:.1f}%)")
    print(f"    Invalid entries: {len(invalid_entries)} ({len(invalid_entries)/len(entries)*100:.1f}%)")
    print("=" * 70)

    # Write filtered playlist if output file specified
    if output_file:
        print(f"\n💾 Writing filtered playlist to: {output_file}")
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write("#EXTM3U\n\n")
            for info, url in valid_entries:
                f.write(f"{info}\n")
                f.write(f"{url}\n\n")
        print(f"✅ Filtered playlist created successfully")

    # List invalid entries
    if invalid_entries and verbose:
        print(f"\n❌ Invalid entries:")
        for info, url in invalid_entries:
            name = "Unknown"
            if 'tvg-name="' in info:
                start = info.index('tvg-name="') + 10
                end = info.index('"', start)
                name = info[start:end]
            print(f"    - {name}")
            print(f"      {url}")


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 validate_playlist_urls.py <input.m3u> [output.m3u]")
        print("\nExamples:")
        print("  python3 validate_playlist_urls.py sample_playlist.m3u")
        print("  python3 validate_playlist_urls.py sample_playlist.m3u filtered_playlist.m3u")
        sys.exit(1)

    input_file = sys.argv[1]
    output_file = sys.argv[2] if len(sys.argv) > 2 else None

    validate_playlist(input_file, output_file, verbose=True)
