"""
Module d'analyse des configurations backend pour Web Sentinel.
Détecte les configurations de sécurité non visibles dans les réponses HTTP.
Version corrigée avec localisation complète.
"""

from __future__ import annotations

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

import requests

from ..localization.helpers import create_translated_finding
from ..model import ScanRequest

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

# Endpoints d'information communs
INFO_ENDPOINTS = [
    '/.well-known/security.txt',
    '/robots.txt',
    '/sitemap.xml',
    '/health',
    '/status',
    '/info',
    '/actuator/health',  # Spring Boot
    '/api/health',
    '/.env',  # Fichier de configuration (ne devrait pas être accessible)
    '/package.json',  # Node.js (ne devrait pas être accessible)
]

# Endpoints typiques des environnements de développement
DEV_ENDPOINTS = [
    '/debug',
    '/test',
    '/dev',
    '/swagger-ui',
    '/api-docs',
    '/phpmyadmin',
    '/adminer',
    '/__debug__',
    '/telescope',  # Laravel Telescope
]


def evaluate_backend_configuration(request: ScanRequest) -> Iterable[Finding]:
    """
    Analyse les configurations de sécurité backend via les endpoints d'information
    et les patterns de configuration accessibles publiquement.
    """
    findings: List[Finding] = []
    
    if not request.allow_invasive:
        findings.append(
            create_translated_finding(
                check="backend-config",
                i18n_key="backend.analysis_requires_invasive",
                severity="info"
            )
        )
        return findings
    
    # Analyse des endpoints publics d'information
    findings.extend(_analyze_public_endpoints(request))
    
    # Analyse des pages d'erreur
    findings.extend(_analyze_error_pages(request))
    
    # Détection d'outils de développement
    findings.extend(_analyze_development_indicators(request))
    
    return findings


def _analyze_public_endpoints(request: ScanRequest) -> List[Finding]:
    """
    Analyse les endpoints publics qui peuvent révéler des informations de configuration.
    """
    findings: List[Finding] = []
    base_url = f"https://{request.domain}"
    
    for endpoint in INFO_ENDPOINTS:
        url = urljoin(base_url, endpoint)
        try:
            response = requests.get(
                url,
                headers={"User-Agent": request.user_agent},
                timeout=request.timeout
            )
            
            if response.status_code == 200:
                if endpoint == '/.well-known/security.txt':
                    findings.append(
                        create_translated_finding(
                            check="backend-config",
                            i18n_key="backend.security_txt_found",
                            severity="info",
                            i18n_params={"endpoint": endpoint, "url": url}
                        )
                    )
                
                elif endpoint in ['/.env', '/package.json']:
                    findings.append(
                        create_translated_finding(
                            check="backend-config",
                            i18n_key="backend.config_file_exposed",
                            severity="high",
                            i18n_params={"endpoint": endpoint, "url": url}
                        )
                    )
                
                elif '/actuator/' in endpoint:
                    content = response.text.lower()
                    if '"diskspace"' in content or '"db"' in content:
                        findings.append(
                            create_translated_finding(
                                check="backend-config",
                                i18n_key="backend.actuator_details_exposed",
                                severity="medium",
                                i18n_params={"url": url}
                            )
                        )
                    
        except requests.RequestException:
            continue
    
    return findings


def _analyze_error_pages(request: ScanRequest) -> List[Finding]:
    """
    Analyse les pages d'erreur pour détecter des fuites d'information sur la configuration.
    """
    findings: List[Finding] = []
    base_url = f"https://{request.domain}"
    
    # Test d'endpoints inexistants pour déclencher des pages d'erreur
    test_endpoints = [
        '/nonexistent-page-12345',
        '/admin/nonexistent',
        '/api/nonexistent',
    ]
    
    for endpoint in test_endpoints:
        url = urljoin(base_url, endpoint)
        try:
            response = requests.get(
                url,
                headers={"User-Agent": request.user_agent},
                timeout=request.timeout
            )
            
            if response.status_code in [404, 500]:
                content = response.text.lower()
                
                # Détection d'informations sensibles dans les erreurs
                if any(pattern in content for pattern in ['stack trace', 'exception', 'debug']):
                    findings.append(
                        create_translated_finding(
                            check="backend-config",
                            i18n_key="backend.verbose_error_pages",
                            severity="medium",
                            i18n_params={"url": url}
                        )
                    )
                    break  # Une seule détection suffit
                    
        except requests.RequestException:
            continue
    
    return findings


def _analyze_development_indicators(request: ScanRequest) -> List[Finding]:
    """
    Détecte les indicateurs suggérant un environnement de développement en production.
    """
    findings: List[Finding] = []
    base_url = f"https://{request.domain}"
    
    for endpoint in DEV_ENDPOINTS:
        url = urljoin(base_url, endpoint)
        try:
            response = requests.get(
                url,
                headers={"User-Agent": request.user_agent},
                timeout=request.timeout
            )
            
            if response.status_code == 200:
                findings.append(
                    create_translated_finding(
                        check="backend-config",
                        i18n_key="backend.dev_tool_accessible",
                        severity="high",
                        i18n_params={"endpoint": endpoint, "url": url}
                    )
                )
                
        except requests.RequestException:
            continue
    
    return findings
