#!/usr/bin/env python3
"""
🌐 Service Local d'API Subscription - Web Sentinel Test Environment

Service HTTP local qui simule l'API cloud pour fournir les tiers d'abonnement
depuis notre base de données locale. Permet à Web Sentinel de récupérer les 
tiers modifiés par notre environnement de test.
"""

import json
import sqlite3
import threading
import time
from datetime import datetime
from http.server import HTTPServer, BaseHTTPRequestHandler
from pathlib import Path
from typing import Optional
from urllib.parse import urlparse, parse_qs

# Configuration
LOCAL_API_PORT = 8765
LOCAL_API_HOST = "localhost"


class SubscriptionAPIHandler(BaseHTTPRequestHandler):
    """Handler pour l'API locale de subscription."""
    
    def __init__(self, *args, **kwargs):
        self.db_path = Path.home() / ".web-sentinel" / "auth.db"
        super().__init__(*args, **kwargs)
    
    def do_GET(self):
        """Gérer les requêtes GET."""
        try:
            parsed_url = urlparse(self.path)
            
            if parsed_url.path == "/subscription/status":
                self._handle_subscription_status()
            elif parsed_url.path == "/health":
                self._handle_health()
            else:
                self._send_error(404, "Not Found")
                
        except Exception as e:
            self._send_error(500, f"Internal Server Error: {str(e)}")
    
    def _handle_subscription_status(self):
        """Gérer la requête de statut d'abonnement."""
        # Récupérer l'Authorization header
        auth_header = self.headers.get('Authorization', '')
        if not auth_header.startswith('Bearer '):
            self._send_error(401, "Unauthorized")
            return
        
        # Pour ce test, on simule que tous les tokens sont valides
        # En production, on vérifierait le token ici
        
        # Récupérer le tier depuis notre base de données
        # Pour simplifier, on utilise le premier utilisateur trouvé
        # En production, on associerait le token à un utilisateur spécifique
        tier = self._get_user_tier_from_db()
        
        response_data = {
            "status": "active",
            "tier": tier,
            "expires_at": None,
            "features": self._get_features_for_tier(tier)
        }
        
        self._send_json_response(200, response_data)
    
    def _handle_health(self):
        """Gérer la requête de santé du service."""
        response_data = {
            "status": "healthy",
            "service": "subscription-api-local",
            "timestamp": datetime.now().isoformat()
        }
        self._send_json_response(200, response_data)
    
    def _get_user_tier_from_db(self) -> str:
        """Récupérer le tier depuis notre base de données locale."""
        try:
            if not self.db_path.exists():
                return "free"
            
            with sqlite3.connect(self.db_path) as conn:
                # Récupérer le premier utilisateur avec un tier défini
                cursor = conn.execute("""
                    SELECT tier FROM user_subscriptions 
                    WHERE tier IS NOT NULL 
                    ORDER BY updated_at DESC 
                    LIMIT 1
                """)
                row = cursor.fetchone()
                
                if row:
                    return row[0]
                else:
                    return "free"
                    
        except Exception as e:
            print(f"Erreur récupération tier: {e}")
            return "free"
    
    def _get_features_for_tier(self, tier: str) -> dict:
        """Obtenir les features selon le tier."""
        features_map = {
            "free": {
                "allow_invasive_tests": False,
                "allow_html_export": False,
                "allow_api_access": False,
                "domain_limit": 3,
                "max_users": 1
            },
            "pro": {
                "allow_invasive_tests": True,
                "allow_html_export": True,
                "allow_api_access": False,
                "domain_limit": -1,
                "max_users": 5
            },
            "enterprise": {
                "allow_invasive_tests": True,
                "allow_html_export": True,
                "allow_api_access": True,
                "domain_limit": -1,
                "max_users": 50
            }
        }
        
        return features_map.get(tier, features_map["free"])
    
    def _send_json_response(self, status_code: int, data: dict):
        """Envoyer une réponse JSON."""
        self.send_response(status_code)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        
        json_data = json.dumps(data, indent=2)
        self.wfile.write(json_data.encode('utf-8'))
    
    def _send_error(self, status_code: int, message: str):
        """Envoyer une erreur."""
        self.send_response(status_code)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        
        error_data = {
            "error": message,
            "status_code": status_code
        }
        json_data = json.dumps(error_data)
        self.wfile.write(json_data.encode('utf-8'))
    
    def log_message(self, format, *args):
        """Supprimer les logs par défaut pour éviter le spam."""
        pass


class LocalSubscriptionAPI:
    """Service API local pour les abonnements."""
    
    def __init__(self, port: int = LOCAL_API_PORT, host: str = LOCAL_API_HOST):
        self.port = port
        self.host = host
        self.server = None
        self.server_thread = None
        self.running = False
    
    def start(self):
        """Démarrer le service API."""
        if self.running:
            print(f"⚠️ Service déjà en cours sur {self.host}:{self.port}")
            return
        
        try:
            self.server = HTTPServer((self.host, self.port), SubscriptionAPIHandler)
            self.server_thread = threading.Thread(target=self.server.serve_forever)
            self.server_thread.daemon = True
            self.server_thread.start()
            self.running = True
            
            print(f"🌐 Service API local démarré sur http://{self.host}:{self.port}")
            print(f"📡 Endpoint: http://{self.host}:{self.port}/subscription/status")
            print(f"🔍 Health check: http://{self.host}:{self.port}/health")
            
        except Exception as e:
            print(f"❌ Erreur démarrage service: {e}")
            self.running = False
    
    def stop(self):
        """Arrêter le service API."""
        if self.server and self.running:
            self.server.shutdown()
            self.server.server_close()
            self.running = False
            print(f"🛑 Service API arrêté")
    
    def is_running(self) -> bool:
        """Vérifier si le service est en cours."""
        return self.running
    
    def get_url(self) -> str:
        """Obtenir l'URL de base du service."""
        return f"http://{self.host}:{self.port}"


def test_api_locally():
    """Tester l'API localement."""
    import requests
    
    api = LocalSubscriptionAPI()
    api.start()
    
    time.sleep(1)  # Attendre que le service démarre
    
    try:
        # Test health check
        print(f"\n🧪 Test de l'API locale...")
        
        health_response = requests.get(f"{api.get_url()}/health", timeout=5)
        if health_response.status_code == 200:
            print(f"✅ Health check OK: {health_response.json()}")
        else:
            print(f"❌ Health check échoué: {health_response.status_code}")
        
        # Test subscription status
        headers = {'Authorization': 'Bearer test-token'}
        sub_response = requests.get(f"{api.get_url()}/subscription/status", headers=headers, timeout=5)
        
        if sub_response.status_code == 200:
            data = sub_response.json()
            print(f"✅ Subscription status OK:")
            print(f"   Tier: {data['tier']}")
            print(f"   Features: {data['features']}")
        else:
            print(f"❌ Subscription status échoué: {sub_response.status_code}")
            
    except Exception as e:
        print(f"❌ Erreur test: {e}")
    
    finally:
        api.stop()


if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description="🌐 Service API Local Subscription")
    parser.add_argument("--test", action="store_true", help="Tester l'API localement")
    parser.add_argument("--port", type=int, default=LOCAL_API_PORT, help="Port du service")
    parser.add_argument("--host", default=LOCAL_API_HOST, help="Host du service")
    
    args = parser.parse_args()
    
    if args.test:
        test_api_locally()
    else:
        # Démarrer le service en continu
        api = LocalSubscriptionAPI(port=args.port, host=args.host)
        api.start()
        
        try:
            print(f"💡 Service en cours... Appuyez sur Ctrl+C pour arrêter")
            while api.is_running():
                time.sleep(1)
        except KeyboardInterrupt:
            print(f"\n🛑 Arrêt du service...")
            api.stop()