"""
Module d'analyse des endpoints API pour Web Sentinel.
Détecte les configurations de sécurité des APIs REST/GraphQL.
Version simplifiée avec localisation complète.
"""

from __future__ import annotations

import json
import logging
from typing import Iterable, List
from urllib.parse import urljoin

import requests

from ..model import Finding, ScanRequest

LOGGER = logging.getLogger("web_sentinel.checks.api_security")

# Endpoints API communs à tester
API_ENDPOINTS = [
    '/api',
    '/api/v1',
    '/api/v2',
    '/rest',
    '/graphql',
    '/webhook',
    '/oauth',
    '/auth',
    '/login',
    '/api/health',
    '/api/status',
]


def evaluate_api_security(request: ScanRequest) -> Iterable[Finding]:
    """
    Analyse la sécurité des endpoints API et leurs configurations.
    """
    findings: List[Finding] = []
    
    if not request.allow_invasive:
        findings.append(
            Finding(
                check="api-security",
                title="API analysis requires invasive mode",
                severity="info",
                description="API security analysis requires --allow-invasive flag for enhanced detection.",
                remediation="Run scan with --allow-invasive if you have legitimate access to the application.",
                impact="Limited to basic endpoint discovery only.",
            )
        )
        return findings
    
    # Découverte des endpoints API
    api_endpoints = _discover_api_endpoints(request)
    
    # Analyse de chaque endpoint trouvé
    for endpoint in api_endpoints:
        findings.extend(_analyze_api_endpoint(request, endpoint))
    
    return findings


def _discover_api_endpoints(request: ScanRequest) -> List[str]:
    """
    Découvre les endpoints API disponibles.
    """
    base_url = f"https://{request.domain}"
    discovered_endpoints = []
    
    for endpoint in API_ENDPOINTS:
        url = urljoin(base_url, endpoint)
        try:
            response = requests.get(
                url,
                headers={"User-Agent": request.user_agent},
                timeout=request.timeout,
                allow_redirects=False
            )
            
            # Considère comme API si retourne JSON ou a des headers API
            content_type = response.headers.get('Content-Type', '').lower()
            if (response.status_code in [200, 401, 403] and 
                ('json' in content_type or 'api' in response.headers.get('Server', '').lower())):
                discovered_endpoints.append(endpoint)
                
        except requests.RequestException:
            continue
    
    return discovered_endpoints


def _analyze_api_endpoint(request: ScanRequest, endpoint: str) -> List[Finding]:
    """
    Analyse un endpoint API spécifique.
    """
    findings: List[Finding] = []
    base_url = f"https://{request.domain}"
    url = urljoin(base_url, endpoint)
    
    try:
        response = requests.get(
            url,
            headers={"User-Agent": request.user_agent},
            timeout=request.timeout
        )
        
        # Vérification CORS permissif
        cors_origin = response.headers.get('Access-Control-Allow-Origin')
        if cors_origin == '*':
            findings.append(
                Finding(
                    check="api-security",
                    title="Permissive CORS on API endpoint",
                    severity="high",
                    description=f"API endpoint {endpoint} allows requests from any origin",
                    remediation="Configure CORS to allow only trusted origins for API endpoints.",
                    evidence="Access-Control-Allow-Origin: *",
                    impact="May enable cross-origin API abuse and data theft.",
                    i18n_key="api.permissive_cors",
                    i18n_params={"endpoint": endpoint}
                )
            )
        
        # Vérification de l'authentification requise
        if response.status_code == 200 and 'Authorization' not in response.request.headers:
            content_type = response.headers.get('Content-Type', '').lower()
            if 'json' in content_type:
                findings.append(
                    Finding(
                        check="api-security",
                        title="API endpoint accessible without authentication",
                        severity="medium",
                        description=f"API endpoint {endpoint} returns data without authentication",
                        remediation="Implement API authentication (API keys, OAuth, JWT tokens).",
                        evidence=f"HTTP {response.status_code} without Authorization header",
                        impact="Unauthenticated API access may expose sensitive data.",
                        i18n_key="api.unauthenticated_access",
                        i18n_params={"endpoint": endpoint, "status": response.status_code}
                    )
                )
        
        # Vérification du rate limiting
        if not any(header.startswith('X-Rate-Limit') for header in response.headers):
            findings.append(
                Finding(
                    check="api-security",
                    title="No rate limiting headers detected",
                    severity="medium",
                    description=f"API endpoint {endpoint} does not show rate limiting headers",
                    remediation="Implement API rate limiting to prevent abuse.",
                    evidence="Missing X-Rate-Limit-* headers",
                    impact="Unprotected APIs may be subject to abuse and DoS attacks.",
                    i18n_key="api.no_rate_limiting",
                    i18n_params={"endpoint": endpoint}
                )
            )
        
    except requests.RequestException as exc:
        findings.append(
            Finding(
                check="api-security",
                title=f"API endpoint {endpoint} unreachable",
                severity="medium",
                description=f"Cannot analyze API endpoint {endpoint}: {exc}",
                remediation="Verify API availability and network connectivity.",
                evidence=f"Endpoint: {url}",
                i18n_key="api.endpoint_unreachable",
                i18n_params={"endpoint": endpoint, "error": str(exc), "url": url}
            )
        )
    
    return findings