#!/usr/bin/env python3
"""
Test de téléchargement d'une vidéo Instagram en simulant un vrai navigateur
"""

import subprocess
import json
import logging
import os
import time
import re
from urllib.parse import urlencode

# Configuration du logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def extract_post_id(url):
    """Extrait l'ID du post Instagram depuis l'URL"""
    patterns = [
        r'instagram\.com/p/([^/]+)',
        r'instagram\.com/reel/([^/]+)',
    ]
    for pattern in patterns:
        match = re.search(pattern, url)
        if match:
            return match.group(1).split('/')[0]
    return None

def get_video_url(url):
    """Récupère l'URL de la vidéo en simulant un vrai navigateur"""
    
    post_id = extract_post_id(url)
    if not post_id:
        logger.error("❌ URL Instagram invalide")
        return None
        
    try:
        # Headers essentiels pour simuler Chrome sur Windows
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.9',
            'Accept-Encoding': 'gzip, deflate, br',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
            'Sec-Ch-Ua': '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"',
            'Sec-Ch-Ua-Mobile': '?0',
            'Sec-Ch-Ua-Platform': '"Windows"',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'DNT': '1',
            'Referer': 'https://www.instagram.com/',
            'X-Requested-With': 'XMLHttpRequest',  # Important pour AJAX
            'X-IG-App-ID': '936619743392459',  # App ID Instagram Web
            'X-ASBD-ID': '129477',  # ID ASBD Instagram
            'X-IG-WWW-Claim': '0',  # Claim par défaut
            'X-CSRFToken': '5678',  # Doit correspondre au cookie csrftoken
            'Origin': 'https://www.instagram.com'
        }
        
        # 1. Récupérer la page avec les bons headers
        # URL avec query params spécifiques Instagram
        query = {
            '__a': '1',  # Demande réponse AJAX
            '__d': 'dis',  # Param Instagram
            '__req': '1',  # Request counter
            '__hs': '19628.HYP:instagram_web_pkg.2.1..0.0',  # Header spécifique
            'dpr': '1',  # Device Pixel Ratio
            '__comet_req': '7',  # Comet request (Facebook)
            '__ccg': 'EXCELLENT',  # Connection Quality
            '__rev': '1008824440',  # Révision client
            '__s': 'y5bz5f:8ilje4:2jrqg4',  # Session ID
            '__hsi': '7321639815273246118',  # Session Hash
            '__spin_r': '1008824440',  # Spin Revision
            '__spin_b': 'trunk',  # Spin Branch
            '__spin_t': str(int(time.time()))  # Timestamp
        }
        
        url_with_params = f'https://www.instagram.com/p/{post_id}/?' + urlencode(query)

        cmd = [
            'curl',
            url_with_params,
            # Cookies essentiels avec valeurs plus réalistes
            '--cookie', 'ig_did=FE7D0EF1-AC24-4B83-81A3-E6424C6B6E13; csrftoken=5678; mid=ZMNHsAALAAEF-EkQpZZ5SKxFXRkc; ig_nrcb=1; datr=6AzDZRnO_ZdYQF56HxN6wnz3; ds_user_id=1234567890; sessionid=9012',
            # Options importantes
            '--compressed',
            '-v',  # Mode verbeux
            '-L',  # Suivre les redirections
            '--max-redirs', '5',  # Limiter les redirections
            '--max-time', '30',  # Timeout
            '-A', headers['User-Agent']  # User Agent
        ]
        
        # Ajouter tous les headers
        for header, value in headers.items():
            if header != 'User-Agent':  # Déjà géré par -A
                cmd.extend(['-H', f'{header}: {value}'])
        
        logger.debug("Récupération de la page du post...")
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()
        
        if process.returncode != 0:
            logger.error(f"❌ Erreur lors de la récupération de la page: {stderr.decode()}")
            return None
            
        html_content = stdout.decode()
        logger.debug(f"Longueur du contenu HTML : {len(html_content)} caractères")
        
        # 2. Rechercher l'URL de la vidéo dans différents formats
        patterns = [
            # Format JSON-LD
            r'<script type="application/ld\+json">(.+?)</script>',
            # Format GraphQL response
            r'"video_url":"([^"]+)"',
            # Format meta tag
            r'<meta property="og:video" content="([^"]+)"',
            # Format video element
            r'<video[^>]+src="([^"]+)"',
            # Format dash manifest
            r'"dash_manifest":"[^"]*BaseURL>([^<]+)<'
        ]
        
        for pattern in patterns:
            matches = re.finditer(pattern, html_content)
            for match in matches:
                try:
                    if '"video_url"' in pattern:
                        # Direct URL in JSON
                        video_url = match.group(1).replace('\\u0026', '&').replace('\\/', '/')
                        logger.debug(f"URL trouvée (format direct) : {video_url}")
                        return video_url
                    elif 'application/ld+json' in pattern:
                        # Parse JSON-LD
                        json_data = json.loads(match.group(1))
                        if isinstance(json_data, dict):
                            video_url = json_data.get('video', {}).get('contentUrl')
                            if video_url:
                                logger.debug(f"URL trouvée (JSON-LD) : {video_url}")
                                return video_url
                    else:
                        # Direct URL in other formats
                        video_url = match.group(1).replace('\\u0026', '&').replace('\\/', '/')
                        if video_url.startswith('http'):
                            logger.debug(f"URL trouvée (format alternatif) : {video_url}")
                            return video_url
                except (json.JSONDecodeError, IndexError) as e:
                    logger.debug(f"Erreur de parsing pour le pattern {pattern}: {str(e)}")
                    continue
        
        # Si aucune URL n'est trouvée, afficher un extrait du HTML pour debug
        logger.error("❌ URL vidéo non trouvée dans le HTML")
        logger.debug("Début du HTML reçu :")
        logger.debug(html_content[:500] + "...")
        return None
        
    except Exception as e:
        logger.error(f"❌ Erreur lors de la récupération : {str(e)}")
        return None

def download_video(video_url, output_dir="downloads"):
    """Télécharge la vidéo avec les bons headers"""
    
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
        
    output_file = os.path.join(output_dir, f"video_{int(time.time())}.mp4")
    
    try:
        # Headers pour le CDN Instagram
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
            'Accept': 'video/webm,video/mp4,video/*;q=0.9',
            'Accept-Language': 'en-US,en;q=0.9',
            'Accept-Encoding': 'gzip, deflate, br',
            'Connection': 'keep-alive',
            'Range': 'bytes=0-',
            'Referer': 'https://www.instagram.com/',
            'Origin': 'https://www.instagram.com',
            'Sec-Fetch-Dest': 'video',
            'Sec-Fetch-Mode': 'no-cors',
            'Sec-Fetch-Site': 'cross-site',
            'Pragma': 'no-cache',
            'Cache-Control': 'no-cache'
        }
        
        cmd = [
            'curl',
            video_url,
            '-L',  # Suivre les redirections
            '-o', output_file,
            '--retry', '3',  # Réessayer 3 fois
            '--retry-delay', '2',  # Attendre 2 secondes entre les essais
            '--cookie', 'ig_did=1234'  # Cookie bidon mais requis
        ]
        
        # Ajouter les headers
        for header, value in headers.items():
            cmd.extend(['-H', f'{header}: {value}'])
            
        logger.info("🔄 Téléchargement de la vidéo...")
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()
        
        if process.returncode == 0 and os.path.exists(output_file):
            if os.path.getsize(output_file) > 0:
                logger.info(f"✅ Vidéo téléchargée: {output_file}")
                return output_file
            else:
                logger.error("❌ Fichier téléchargé vide")
                os.remove(output_file)
                return None
        else:
            logger.error(f"❌ Erreur lors du téléchargement: {stderr.decode()}")
            return None
            
    except Exception as e:
        logger.error(f"❌ Erreur: {str(e)}")
        if os.path.exists(output_file):
            os.remove(output_file)
        return None

def download_instagram_video(url):
    """Télécharge une vidéo Instagram"""
    
    logger.info(f"🔄 Téléchargement depuis Instagram: {url}")
    
    # 1. Obtenir l'URL de la vidéo
    video_url = get_video_url(url)
    if not video_url:
        return None
        
    logger.debug(f"URL vidéo trouvée : {video_url}")
    
    # 2. Télécharger la vidéo
    return download_video(video_url)

if __name__ == "__main__":
    url = "https://www.instagram.com/reel/DMpc37-tJdF/"
    result = download_instagram_video(url)
    
    if result:
        print(f"\n✅ Vidéo téléchargée avec succès: {result}")
    else:
        print("\n❌ Échec du téléchargement")
