# web_sentinel_api_simple.py - API simplifiée sans base de données
from flask import Flask, request, jsonify
from flask_cors import CORS
import os
import tempfile
from datetime import datetime
import logging

from web_sentinel.scanner import SentinelScanner
from web_sentinel.model import ScanRequest

# Configuration Flask
app = Flask(__name__)

# Extensions
CORS(app, origins=['https://web-sentinel.taaazzz-prog.fr', 'https://*.taaazzz-prog.fr', 'http://localhost:*'])

# Configuration des logs
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Clé API statique pour les tests
DEMO_API_KEY = "ws_demo_test_key_for_colleagues"

def validate_api_key(key: str) -> bool:
    """Valider une clé API (version simplifiée)."""
    return key == DEMO_API_KEY

@app.route('/api/v1/health')
def health():
    """Endpoint de santé."""
    return jsonify({
        'status': 'healthy',
        'version': '1.0.0',
        'timestamp': datetime.utcnow().isoformat(),
        'server': 'web-sentinel.taaazzz-prog.fr'
    })

@app.route('/api/v1/register', methods=['POST'])
def register_api_key():
    """Enregistrer une nouvelle clé API (version demo)."""
    try:
        data = request.get_json()
        
        name = data.get('name', 'Demo User')
        email = data.get('email', 'demo@example.com')
        
        logger.info(f"Demo API key generated for {email}")
        
        return jsonify({
            'api_key': DEMO_API_KEY,
            'tier': 'demo',
            'daily_limit': 100,
            'monthly_limit': 1000,
            'message': 'Demo API key generated successfully'
        })
        
    except Exception as e:
        logger.error(f"Error registering API key: {e}")
        return jsonify({'error': 'Internal server error'}), 500

@app.route('/api/v1/scan-source', methods=['POST'])
def scan_source_code():
    """Scanner du code source."""
    try:
        data = request.get_json()
        if not data:
            return jsonify({'error': 'JSON payload required'}), 400
        
        # Validation de l'API key
        api_key_str = data.get('api_key')
        if not validate_api_key(api_key_str):
            return jsonify({'error': 'Invalid or missing API key'}), 401
        
        # Paramètres
        source_content = data.get('source_content')
        if not source_content:
            return jsonify({'error': 'source_content required'}), 400
        
        file_path = data.get('file_path', 'unknown.txt')
        language = data.get('language', 'auto')
        
        # Simulation d'analyse de code source
        findings = []
        
        # Détecter quelques vulnérabilités communes
        if 'password' in source_content.lower() and '=' in source_content:
            findings.append({
                'check': 'hardcoded-credentials',
                'title': 'Mot de passe codé en dur détecté',
                'severity': 'high',
                'description': 'Un mot de passe semble être codé directement dans le code source',
                'remediation': 'Utilisez des variables d\'environnement ou un gestionnaire de secrets',
                'line': source_content.lower().find('password') // 50 + 1
            })
        
        if 'eval(' in source_content or 'exec(' in source_content:
            findings.append({
                'check': 'code-injection',
                'title': 'Injection de code possible',
                'severity': 'critical',
                'description': 'Usage de eval() ou exec() détecté',
                'remediation': 'Évitez l\'exécution dynamique de code non validé',
                'line': max(source_content.find('eval('), source_content.find('exec(')) // 50 + 1
            })
        
        if 'sql' in source_content.lower() and any(op in source_content for op in ['+', '%', 'format']):
            findings.append({
                'check': 'sql-injection',
                'title': 'Injection SQL potentielle',
                'severity': 'high', 
                'description': 'Concaténation de chaînes dans une requête SQL détectée',
                'remediation': 'Utilisez des requêtes préparées ou un ORM',
                'line': source_content.lower().find('sql') // 50 + 1
            })
        
        logger.info(f"Source scan completed for {api_key_str}: {len(findings)} findings")
        
        return jsonify({
            'status': 'success',
            'scan_id': f"src_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}",
            'timestamp': datetime.utcnow().isoformat(),
            'file_path': file_path,
            'language': language,
            'findings': findings,
            'summary': {
                'total': len(findings),
                'by_severity': {
                    'critical': len([f for f in findings if f['severity'] == 'critical']),
                    'high': len([f for f in findings if f['severity'] == 'high']),
                    'medium': len([f for f in findings if f['severity'] == 'medium']),
                    'low': len([f for f in findings if f['severity'] == 'low'])
                }
            }
        })
        
    except Exception as e:
        logger.error(f"Error in source scan: {e}")
        return jsonify({'error': 'Internal server error'}), 500

@app.route('/api/v1/scan-domain', methods=['POST'])
def scan_domain():
    """Scanner un domaine (utilise votre scanner existant)."""
    try:
        data = request.get_json()
        if not data:
            return jsonify({'error': 'JSON payload required'}), 400
        
        # Validation API key
        api_key_str = data.get('api_key')
        if not validate_api_key(api_key_str):
            return jsonify({'error': 'Invalid or missing API key'}), 401
        
        domain = data.get('domain')
        if not domain:
            return jsonify({'error': 'domain required'}), 400
        
        options = data.get('options', {})
        
        # Utiliser votre scanner existant
        request_obj = ScanRequest(
            domain=domain,
            timeout=options.get('timeout', 5.0),
            allow_invasive=options.get('allow_invasive', False)
        )
        
        scanner = SentinelScanner()
        modules = options.get('modules', ['headers', 'tls'])
        
        result = scanner.run(request_obj, modules)
        
        logger.info(f"Domain scan completed for {api_key_str}: {domain}")
        
        # Formatter la réponse
        findings = [
            {
                'check': f.check,
                'title': f.title,
                'severity': f.severity,
                'description': f.description,
                'remediation': f.remediation
            } for f in result.findings
        ]
        
        return jsonify({
            'status': 'success',
            'scan_id': f"dom_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}",
            'timestamp': datetime.utcnow().isoformat(),
            'domain': domain,
            'findings': findings,
            'summary': {
                'total': len(findings),
                'by_severity': {
                    'critical': len([f for f in findings if f['severity'] == 'critical']),
                    'high': len([f for f in findings if f['severity'] == 'high']),
                    'medium': len([f for f in findings if f['severity'] == 'medium']),
                    'low': len([f for f in findings if f['severity'] == 'low'])
                }
            }
        })
        
    except Exception as e:
        logger.error(f"Error in domain scan: {e}")
        return jsonify({'error': f'Internal server error: {e}'}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)