// ========================================
// GÉNÉRATEUR AUTOMATIQUE DE TESTS
// Scan des modules lib/ et génération de tests systématiques
// ========================================

const fs = require('fs').promises;
const path = require('path');
const { logSh } = require('../../lib/ErrorReporting');

/**
 * Générateur automatique de tests pour tous les modules lib/
 * Analyse AST et génère des tests adaptés au type de fonction
 */
class ModuleTestGenerator {
  
  static LIB_PATH = path.join(__dirname, '../../lib');
  static GENERATED_TESTS_PATH = path.join(__dirname, './generated');
  
  // Types de fonctions identifiables
  static FUNCTION_TYPES = {
    ASYNC: 'async',
    SYNC: 'sync',
    CONTENT_GENERATOR: 'content',
    VALIDATOR: 'validator',
    UTILITY: 'utility',
    CLASS_METHOD: 'method',
    EXPORT_FUNCTION: 'export'
  };
  
  /**
   * 🚀 GÉNÉRATION COMPLÈTE TESTS - ORCHESTRATEUR PRINCIPAL
   * 
   * CE QUI EST TESTÉ :
   * ✅ Scan récursif dossier lib/ pour détecter tous modules .js
   * ✅ Génération automatique tests adaptés par type fonction
   * ✅ Création master test runner pour exécution batch
   * ✅ Statistiques complètes : générés, échecs, couverture
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - scanLibModules() : scan récursif avec filter .js non-test
   * - Pour chaque module : analyzeModule() + generateTestCases() + writeTestFile()
   * - generateMasterTestRunner() pour orchestration globale
   * - Logging détaillé avec ErrorReporting.logSh()
   */
  static async generateAllTests() {
    try {
      logSh('🔧 Démarrage génération automatique des tests', 'INFO');
      
      // Création du dossier de tests générés
      await this.ensureGeneratedDirectory();
      
      // Scan de tous les modules lib/
      const modules = await this.scanLibModules();
      logSh(`📦 ${modules.length} modules détectés`, 'DEBUG');
      
      const results = {
        generated: 0,
        skipped: 0,
        errors: 0,
        modules: []
      };
      
      // Génération pour chaque module
      for (const modulePath of modules) {
        try {
          const moduleResult = await this.generateTestsForModule(modulePath);
          results.modules.push(moduleResult);
          results.generated++;
          
          logSh(`✅ Tests générés: ${path.basename(modulePath)}`, 'DEBUG');
          
        } catch (error) {
          logSh(`❌ Erreur génération ${path.basename(modulePath)}: ${error.message}`, 'ERROR');
          results.errors++;
        }
      }
      
      // Génération du test runner global
      await this.generateMasterTestRunner(results.modules);
      
      logSh(`🎯 Génération terminée: ${results.generated} générés, ${results.errors} erreurs`, 'INFO');
      return results;
      
    } catch (error) {
      logSh(`💥 Erreur génération globale: ${error.message}`, 'ERROR');
      throw error;
    }
  }
  
  /**
   * 🎯 GÉNÉRATION TESTS MODULE SPÉCIFIQUE - PIPELINE INDIVIDUEL
   * 
   * CE QUI EST TESTÉ :
   * ✅ Analyse statique complète : fonctions, classes, exports, dépendances
   * ✅ Génération cas tests adaptés au type (async, validator, generator, etc.)
   * ✅ Écriture fichier test avec imports et structure Node.js
   * ✅ Calcul métrique couverture (% fonctions testées)
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - analyzeModule() pour extraction AST complète
   * - generateTestCases() avec templates spécialisés
   * - writeTestFile() avec structure Node.js Test Runner
   * - calculateCoverage() pour métriques qualité
   */
  static async generateTestsForModule(modulePath) {
    const analysis = await this.analyzeModule(modulePath);
    const tests = await this.generateTestCases(analysis);
    const testFilePath = await this.writeTestFile(analysis, tests);
    
    return {
      modulePath,
      testFilePath,
      analysis,
      testCount: tests.length,
      coverage: this.calculateCoverage(analysis, tests)
    };
  }
  
  /**
   * 🔍 ANALYSE MODULE - EXTRACTEUR AST COMPLET
   * 
   * CE QUI EST TESTÉ :
   * ✅ Lecture fichier + parsing relatif paths pour imports
   * ✅ Extraction 4 types : fonctions, classes, exports, dépendances
   * ✅ Analyse signature fonctions (async, params, type)
   * ✅ Construction structure analysis unifiée
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - fs.readFile() + path.relative() pour chemins
   * - extractFunctions() avec regex patterns multiples
   * - extractClasses() + extractExports() + extractDependencies()
   * - Return analysis object complet pour génération tests
   */
  static async analyzeModule(modulePath) {
    const content = await fs.readFile(modulePath, 'utf8');
    const relativePath = path.relative(this.LIB_PATH, modulePath);
    const moduleName = path.basename(modulePath, '.js');
    
    const analysis = {
      modulePath,
      relativePath,
      moduleName,
      content,
      functions: [],
      classes: [],
      exports: [],
      dependencies: []
    };
    
    // Extraction des fonctions
    analysis.functions = this.extractFunctions(content);
    
    // Extraction des classes
    analysis.classes = this.extractClasses(content);
    
    // Extraction des exports
    analysis.exports = this.extractExports(content);
    
    // Extraction des dépendances
    analysis.dependencies = this.extractDependencies(content);
    
    return analysis;
  }
  
  /**
   * 🔧 EXTRACTION FONCTIONS - PARSER REGEX AVANCÉ
   * 
   * CE QUI EST TESTÉ :
   * ✅ 4 patterns regex : async function, function normale, arrow functions, méthodes classe
   * ✅ Extraction nom + paramètres + détection async
   * ✅ Classification automatique type fonction (generator, validator, utility, etc.)
   * ✅ Déduplication et filtrage (skip constructor, méthodes privées)
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - 4 regex patterns avec exec() loop pour toutes occurrences
   * - determineFunctionType() selon nom et signature
   * - Params parsing : split(',') + trim + filter vides
   * - Dedup avec find() pour éviter doublons par nom
   */
  static extractFunctions(content) {
    const functions = [];
    
    // Patterns pour différents types de fonctions
    const patterns = [
      // Fonctions async
      /async\s+function\s+(\w+)\s*\(([^)]*)\)/g,
      // Fonctions normales
      /(?:^|\n)\s*function\s+(\w+)\s*\(([^)]*)\)/g,
      // Fonctions fléchées avec nom
      /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g,
      // Méthodes de classe
      /(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{/g
    ];
    
    patterns.forEach((pattern, index) => {
      let match;
      while ((match = pattern.exec(content)) !== null) {
        const functionName = match[1];
        const params = match[2] || '';
        
        // Skip constructors et méthodes privées
        if (functionName === 'constructor' || functionName.startsWith('_')) continue;
        
        const func = {
          name: functionName,
          params: params.split(',').map(p => p.trim()).filter(p => p),
          isAsync: match[0].includes('async'),
          type: this.determineFunctionType(functionName, match[0], content),
          fullMatch: match[0],
          index: match.index
        };
        
        // Éviter les doublons
        if (!functions.find(f => f.name === functionName)) {
          functions.push(func);
        }
      }
    });
    
    return functions;
  }
  
  /**
   * 🏢 EXTRACTION CLASSES - DÉTECTEUR ORIENTÉ OBJET
   * 
   * CE QUI EST TESTÉ :
   * ✅ Regex pattern class avec support héritage (extends)
   * ✅ Extraction méthodes classe via extractClassMethods()
   * ✅ Construction structure class complète avec metadata
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Pattern : /class\s+(\w+)(?:\s+extends\s+(\w+))?\s*\{/g
   * - Pour chaque match : extraction nom + parent class
   * - extractClassMethods() pour lister méthodes publiques
   * - Return array classes avec nom, extends, méthodes
   */
  static extractClasses(content) {
    const classes = [];
    const classPattern = /class\s+(\w+)(?:\s+extends\s+(\w+))?\s*\{/g;
    
    let match;
    while ((match = classPattern.exec(content)) !== null) {
      classes.push({
        name: match[1],
        extends: match[2],
        methods: this.extractClassMethods(content, match.index)
      });
    }
    
    return classes;
  }
  
  /**
   * 📦 EXTRACTION EXPORTS - DÉTECTEUR MODULE INTERFACE
   * 
   * CE QUI EST TESTÉ :
   * ✅ 2 patterns : module.exports = {...} et exports.functionName
   * ✅ Parsing object exports avec support syntax variations
   * ✅ Déduplication avec Set pour éviter doublons
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Pattern 1 : /module\.exports\s*=\s*\{([^}]+)\}/s pour block exports
   * - Pattern 2 : /exports\.(\w+)/g pour named exports individuels
   * - Parsing object syntax avec split(':') pour key:value
   * - [...new Set(exports)] pour déduplication finale
   */
  static extractExports(content) {
    const exports = [];
    
    // module.exports = { ... }
    const moduleExportsMatch = content.match(/module\.exports\s*=\s*\{([^}]+)\}/s);
    if (moduleExportsMatch) {
      const exportsContent = moduleExportsMatch[1];
      const exportNames = exportsContent.match(/(\w+)(?:\s*:\s*\w+)?/g) || [];
      exports.push(...exportNames.map(name => name.split(':')[0].trim()));
    }
    
    // exports.functionName
    const namedExportsPattern = /exports\.(\w+)/g;
    let match;
    while ((match = namedExportsPattern.exec(content)) !== null) {
      exports.push(match[1]);
    }
    
    return [...new Set(exports)]; // Déduplication
  }
  
  /**
   * 🔗 EXTRACTION DÉPENDANCES - DÉTECTEUR IMPORTS
   * 
   * CE QUI EST TESTÉ :
   * ✅ Détection statements require() avec support quotes multiples
   * ✅ Extraction noms modules pour génération imports tests
   * ✅ Support syntax variations : require('module'), require("module")
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Pattern : /require\(['\"\`]([^'\"\`]+)['\"\`]\)/g
   * - Exec loop pour toutes occurrences
   * - Capture groupe 1 pour nom module
   * - Return array pour imports générés
   */
  static extractDependencies(content) {
    const dependencies = [];
    
    // require statements
    const requirePattern = /require\(['"`]([^'"`]+)['"`]\)/g;
    let match;
    while ((match = requirePattern.exec(content)) !== null) {
      dependencies.push(match[1]);
    }
    
    return dependencies;
  }
  
  /**
   * 🏷️ DÉTERMINATION TYPE FONCTION - CLASSIFICATEUR INTELLIGENT
   * 
   * CE QUI EST TESTÉ :
   * ✅ Classification 6 types selon nom et signature
   * ✅ CONTENT_GENERATOR : generate|create|build dans nom
   * ✅ VALIDATOR : validate|check|verify dans nom
   * ✅ ASYNC : signature.includes('async')
   * ✅ UTILITY : format|parse|calculate dans nom
   * ✅ Fallback SYNC pour autres
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Séquence if conditions avec includes() sur nom fonction
   * - Priority order : generator > validator > async > utility > sync
   * - Return FUNCTION_TYPES enum pour template selection
   */
  static determineFunctionType(name, signature, content) {
    // Fonction de génération de contenu
    if (name.includes('generate') || name.includes('create') || name.includes('build')) {
      return this.FUNCTION_TYPES.CONTENT_GENERATOR;
    }
    
    // Fonction de validation
    if (name.includes('validate') || name.includes('check') || name.includes('verify')) {
      return this.FUNCTION_TYPES.VALIDATOR;
    }
    
    // Fonction async
    if (signature.includes('async')) {
      return this.FUNCTION_TYPES.ASYNC;
    }
    
    // Fonction utilitaire
    if (name.includes('format') || name.includes('parse') || name.includes('calculate')) {
      return this.FUNCTION_TYPES.UTILITY;
    }
    
    return this.FUNCTION_TYPES.SYNC;
  }
  
  /**
   * 🧪 GÉNÉRATION CAS TESTS - FACTORY TEMPLATE TESTS
   * 
   * CE QUI EST TESTÉ :
   * ✅ Génération tests fonctions avec templates spécialisés
   * ✅ Génération tests exports (vérification disponibilité)
   * ✅ Test intégration général module health check
   * ✅ Selection template selon function type
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Loop analysis.functions : generateFunctionTest() pour chaque
   * - Loop analysis.exports : generateExportTest() pour disponibilité
   * - generateIntegrationTest() pour health check global
   * - Return array complet tests pour writeTestFile()
   */
  static async generateTestCases(analysis) {
    const tests = [];
    
    // Tests pour les fonctions
    for (const func of analysis.functions) {
      const testCase = await this.generateFunctionTest(func, analysis);
      if (testCase) tests.push(testCase);
    }
    
    // Tests pour les exports
    for (const exportName of analysis.exports) {
      const exportTest = this.generateExportTest(exportName, analysis);
      if (exportTest) tests.push(exportTest);
    }
    
    // Test d'intégration général
    tests.push(this.generateIntegrationTest(analysis));
    
    return tests;
  }
  
  /**
   * 🎯 GÉNÉRATION TEST FONCTION - TEMPLATE SELECTOR
   * 
   * CE QUI EST TESTÉ :
   * ✅ Switch selon function type pour template approprié
   * ✅ Templates spécialisés : ContentGenerator, Validator, Async, Basic
   * ✅ Génération inputs mockés selon paramètres fonction
   * ✅ Structure test object avec metadata
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Switch func.type pour sélection template method
   * - getContentGeneratorTestTemplate() avec validation IA
   * - getValidatorTestTemplate() avec valid/invalid inputs
   * - getAsyncTestTemplate() avec timeout et duration
   * - getBasicTestTemplate() pour fonctions standard
   */
  static async generateFunctionTest(func, analysis) {
    let testTemplate;
    
    switch (func.type) {
      case this.FUNCTION_TYPES.CONTENT_GENERATOR:
        testTemplate = this.getContentGeneratorTestTemplate(func, analysis);
        break;
      case this.FUNCTION_TYPES.VALIDATOR:
        testTemplate = this.getValidatorTestTemplate(func, analysis);
        break;
      case this.FUNCTION_TYPES.ASYNC:
        testTemplate = this.getAsyncTestTemplate(func, analysis);
        break;
      default:
        testTemplate = this.getBasicTestTemplate(func, analysis);
    }
    
    return {
      name: `${func.name}_test`,
      type: func.type,
      template: testTemplate,
      function: func
    };
  }
  
  /**
   * 📝 TEMPLATE CONTENT GENERATOR - TEST GÉNÉRATION CONTENU
   * 
   * CE QUI EST TESTÉ :
   * ✅ Exécution fonction génération avec mock input
   * ✅ Validations base : result exists, type string/object
   * ✅ Validation qualité IA si contenu texte >50 chars
   * ✅ Seuil qualité : AIContentValidator score >= 40
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Génération mockInput adapté aux paramètres
   * - Assert basiques : result truthy + type check
   * - If string + length>50 : AIContentValidator.quickValidate()
   * - Assert validation.overall >= 40 pour qualité acceptable
   */
  static getContentGeneratorTestTemplate(func, analysis) {
    return `
  test('${func.name} - Content Generation', async () => {
    const mockInput = ${this.generateMockInput(func)};
    
    try {
      const result = await ${analysis.moduleName}.${func.name}(mockInput);
      
      // Validations de base
      assert.ok(result, 'Should return a result');
      assert.ok(typeof result === 'string' || typeof result === 'object', 'Should return content');
      
      // Validation IA si contenu texte
      if (typeof result === 'string' && result.length > 50) {
        const validation = await AIContentValidator.quickValidate(result, {
          context: 'Generated content test'
        });
        assert.ok(validation.overall >= 40, 'Content quality should be acceptable');
      }
      
      console.log('✅ ${func.name}: Content generated successfully');
      
    } catch (error) {
      console.error('❌ ${func.name}: Generation failed:', error.message);
      throw error;
    }
  });`;
  }
  
  /**
   * ✅ TEMPLATE VALIDATOR - TEST FONCTION VALIDATION
   * 
   * CE QUI EST TESTÉ :
   * ✅ Test input valide : doit retourner résultat (pas undefined)
   * ✅ Test input invalide : doit retourner false ou throw error
   * ✅ Gestion gracieuse erreurs attendues validation
   * ✅ Vérification comportement correct selon type retour
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - generateValidInput() + generateInvalidInput() pour cas tests
   * - Assert validResult !== undefined pour success case
   * - Try/catch sur invalid : si boolean=false OU exception OK
   * - Console.log expected errors pour debugging
   */
  static getValidatorTestTemplate(func, analysis) {
    return `
  test('${func.name} - Validation', async () => {
    const validInput = ${this.generateValidInput(func)};
    const invalidInput = ${this.generateInvalidInput(func)};
    
    try {
      // Test avec input valide
      const validResult = await ${analysis.moduleName}.${func.name}(validInput);
      assert.ok(validResult !== undefined, 'Should return result for valid input');
      
      // Test avec input invalide
      try {
        const invalidResult = await ${analysis.moduleName}.${func.name}(invalidInput);
        // Si pas d'erreur, vérifier que la validation échoue
        if (typeof invalidResult === 'boolean') {
          assert.strictEqual(invalidResult, false, 'Should return false for invalid input');
        }
      } catch (error) {
        // C'est attendu pour une validation qui throw
        console.log('Expected validation error:', error.message);
      }
      
      console.log('✅ ${func.name}: Validation working correctly');
      
    } catch (error) {
      console.error('❌ ${func.name}: Validation test failed:', error.message);
      throw error;
    }
  });`;
  }
  
  /**
   * ⏱️ TEMPLATE ASYNC - TEST FONCTION ASYNCHRONE
   * 
   * CE QUI EST TESTÉ :
   * ✅ Exécution async avec mesure durée (performance)
   * ✅ Timeout 30 secondes max (assert duration < 30000ms)
   * ✅ Vérification résultat non undefined
   * ✅ Logging durée exécution pour monitoring
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Date.now() avant/après pour mesure durée
   * - await func() avec mockInput généré
   * - Assert result + assert duration < 30000
   * - Console.log avec template literal pour durée
   */
  static getAsyncTestTemplate(func, analysis) {
    return `
  test('${func.name} - Async Operation', async () => {
    const input = ${this.generateMockInput(func)};
    
    try {
      const startTime = Date.now();
      const result = await ${analysis.moduleName}.${func.name}(input);
      const duration = Date.now() - startTime;
      
      // Validations de base
      assert.ok(result !== undefined, 'Should return a result');
      assert.ok(duration < 30000, 'Should complete within 30 seconds');
      
      console.log(\`✅ ${func.name}: Completed in \${duration}ms\`);
      
    } catch (error) {
      console.error('❌ ${func.name}: Async operation failed:', error.message);
      throw error;
    }
  });`;
  }
  
  /**
   * 🔧 TEMPLATE BASIC - TEST FONCTION STANDARD
   * 
   * CE QUI EST TESTÉ :
   * ✅ Exécution synchrone fonction avec mock input
   * ✅ Validations minimales : result !== undefined
   * ✅ Type checking basique pour éviter crashes
   * ✅ Gestion erreurs avec logging pour debugging
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Génération mockInput via generateMockInput()
   * - Appel direct fonction (pas await)
   * - Double assert : !== undefined + typeof check
   * - Try/catch avec console.error pour troubleshooting
   */
  static getBasicTestTemplate(func, analysis) {
    return `
  test('${func.name} - Basic Function', () => {
    const input = ${this.generateMockInput(func)};
    
    try {
      const result = ${analysis.moduleName}.${func.name}(input);
      
      // Validations de base
      assert.ok(result !== undefined, 'Should return a result');
      assert.ok(typeof result !== 'undefined', 'Result should be defined');
      
      console.log('✅ ${func.name}: Function executed successfully');
      
    } catch (error) {
      console.error('❌ ${func.name}: Function failed:', error.message);
      throw error;
    }
  });`;
  }
  
  /**
   * 🎭 GÉNÉRATION INPUTS MOCKÉS - FACTORY DONNÉES TEST
   * 
   * CE QUI EST TESTÉ :
   * ✅ Génération données test adaptées selon noms paramètres
   * ✅ Mapping intelligent : 'content' → texte, 'data' → CSV object, etc.
   * ✅ Support paramètres multiples avec array notation
   * ✅ Fallback 'test_value' pour paramètres non reconnus
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - If params.length=0 : return 'undefined'
   * - Map params : content→text, data→CSV, personality→profile, options→config
   * - Single param : return direct, multiple : return [array]
   * - Smart defaults pour testing réaliste
   */
  static generateMockInput(func) {
    if (func.params.length === 0) return 'undefined';
    
    const mockInputs = func.params.map(param => {
      if (param.includes('content')) return '"Test content for validation"';
      if (param.includes('data') || param.includes('csv')) return '{ mc0: "test keyword", t0: "Test title" }';
      if (param.includes('personality')) return '{ nom: "Marc", style: "technique" }';
      if (param.includes('options')) return '{ test: true }';
      if (param.includes('text')) return '"Sample text for processing"';
      return '"test_value"';
    });
    
    return mockInputs.length === 1 ? mockInputs[0] : `[${mockInputs.join(', ')}]`;
  }
  
  static generateValidInput(func) {
    return this.generateMockInput(func);
  }
  
  static generateInvalidInput(func) {
    if (func.params.length === 0) return 'undefined';
    return 'null';
  }
  
  /**
   * 📝 ÉCRITURE FICHIER TEST - GÉNÉRATEUR FICHIER
   * 
   * CE QUI EST TESTÉ :
   * ✅ Construction nom fichier : moduleName + '.generated.test.js'
   * ✅ Génération contenu complet avec buildTestFileContent()
   * ✅ Écriture fichier dans dossier GENERATED_TESTS_PATH
   * ✅ Return path pour référence dans results
   * 
   * ALGORITHME EXÉCUTÉ :
   * - path.join(GENERATED_TESTS_PATH, fileName) pour chemin complet
   * - buildTestFileContent() avec imports + tests + structure
   * - fs.writeFile() avec encoding utf8
   * - Return testFilePath pour tracking
   */
  static async writeTestFile(analysis, tests) {
    const testFileName = `${analysis.moduleName}.generated.test.js`;
    const testFilePath = path.join(this.GENERATED_TESTS_PATH, testFileName);
    
    const testContent = this.buildTestFileContent(analysis, tests);
    
    await fs.writeFile(testFilePath, testContent, 'utf8');
    
    return testFilePath;
  }
  
  /**
   * 🏧 CONSTRUCTION CONTENU FICHIER - BUILDER TEMPLATE COMPLET
   * 
   * CE QUI EST TESTÉ :
   * ✅ Header avec metadata : module path, date génération, etc.
   * ✅ Imports automatiques : assert, node:test, module cible + dépendances
   * ✅ Structure describe() avec setup + tests générés + integration
   * ✅ Test module loading + health check avec exports listing
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - generateImports() pour imports nécessaires (IA validator si content tests)
   * - Template string avec placeholders : moduleName, date, tests
   * - Concat tests.map(test => test.template) pour tous cas
   * - Integration test avec Object.keys() pour exports check
   */
  static buildTestFileContent(analysis, tests) {
    const imports = this.generateImports(analysis);
    const testCases = tests.map(test => test.template).join('\n');
    
    return `// ========================================
// TESTS GÉNÉRÉS AUTOMATIQUEMENT - ${analysis.moduleName}
// Module: ${analysis.relativePath}
// Générés le: ${new Date().toISOString()}
// ========================================

const assert = require('assert');
const { test, describe } = require('node:test');
${imports}

describe('${analysis.moduleName} - Tests automatiques', () => {
  
  // Setup avant les tests
  let testContext = {};
  
  test('Module loading', () => {
    assert.ok(${analysis.moduleName}, 'Module should be loaded');
    console.log('📦 Module ${analysis.moduleName} loaded successfully');
  });

${testCases}
  
  // Test d'intégration général
  test('Integration - Module health check', async () => {
    try {
      // Vérification exports
      const exports = Object.keys(${analysis.moduleName});
      assert.ok(exports.length > 0, 'Module should export functions');
      
      console.log(\`✅ ${analysis.moduleName}: \${exports.length} exports available\`);
      console.log('📋 Exports:', exports.join(', '));
      
    } catch (error) {
      console.error('❌ Integration test failed:', error.message);
      throw error;
    }
  });
});`;
  }
  
  /**
   * 📦 GÉNÉRATION IMPORTS NÉCESSAIRES - DÉTECTEUR DÉPENDANCES
   * 
   * CE QUI EST TESTÉ :
   * ✅ Import module cible avec chemin relatif corrigé
   * ✅ Détection tests contenu pour import AIContentValidator
   * ✅ Construction array imports pour injection template
   * ✅ Chemins relatifs adaptés structure dossiers
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Import base : require('../../relativePath') pour module
   * - hasContentTests = analysis.functions avec CONTENT_GENERATOR type
   * - If hasContentTests : add AIContentValidator import
   * - Return imports.join('\n') pour template injection
   */
  static generateImports(analysis) {
    const imports = [`const ${analysis.moduleName} = require('../../${analysis.relativePath}');`];
    
    // Import du validateur IA si tests de contenu
    const hasContentTests = analysis.functions.some(f => 
      f.type === this.FUNCTION_TYPES.CONTENT_GENERATOR
    );
    
    if (hasContentTests) {
      imports.push("const { AIContentValidator } = require('../validators/AIContentValidator');");
    }
    
    return imports.join('\n');
  }
  
  /**
   * 📊 CALCUL COUVERTURE - MÉTRIQUE QUALITÉ TESTS
   * 
   * CE QUI EST TESTÉ :
   * ✅ Comptage total fonctions + exports disponibles
   * ✅ Comptage tests générés (exclusion type integration)
   * ✅ Calcul pourcentage couverture avec protection division zéro
   * ✅ Return métriques détaillées pour reporting
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - totalFunctions = analysis.functions.length + analysis.exports.length
   * - testedFunctions = tests.filter(t => t.type !== 'integration').length
   * - percentage = Math.round((tested/total)*100) avec protection >0
   * - Return {total, tested, percentage} pour dashboard
   */
  static calculateCoverage(analysis, tests) {
    const totalFunctions = analysis.functions.length + analysis.exports.length;
    const testedFunctions = tests.filter(t => t.type !== 'integration').length;
    
    return {
      total: totalFunctions,
      tested: testedFunctions,
      percentage: totalFunctions > 0 ? Math.round((testedFunctions / totalFunctions) * 100) : 0
    };
  }
  
  /**
   * 📁 UTILITAIRE CRÉATION DOSSIER - SETUP ENVIRONNEMENT
   * 
   * CE QUI EST TESTÉ :
   * ✅ Vérification existence dossier GENERATED_TESTS_PATH
   * ✅ Création automatique si inexistant avec recursive:true
   * ✅ Gestion gracieuse erreurs accès fichiers
   * 
   * ALGORITHME EXÉCUTÉ :
   * - fs.access() pour test existence
   * - Si erreur : fs.mkdir() avec {recursive:true}
   * - Try/catch pattern pour gestion erreurs
   */
  static async ensureGeneratedDirectory() {
    try {
      await fs.access(this.GENERATED_TESTS_PATH);
    } catch (error) {
      await fs.mkdir(this.GENERATED_TESTS_PATH, { recursive: true });
    }
  }
  
  /**
   * 🔍 SCAN MODULES LIB - EXPLORATEUR RÉCURSIF
   * 
   * CE QUI EST TESTÉ :
   * ✅ Scan récursif dossier lib/ avec exploration sous-dossiers
   * ✅ Filtrage .js files excluant fichiers test existants
   * ✅ Construction liste complète chemins absolus modules
   * ✅ Support structure dossiers imbriqués (adversarial/, generation/, etc.)
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - scanDirectory() récursif avec fs.readdir({withFileTypes:true})
   * - Pour chaque item : if directory → recurse, if .js file → add
   * - Filter : item.name.endsWith('.js') && !item.name.includes('test')
   * - Return array paths absolus pour generateAllTests()
   */
  static async scanLibModules() {
    const modules = [];
    
    const scanDirectory = async (dirPath) => {
      const items = await fs.readdir(dirPath, { withFileTypes: true });
      
      for (const item of items) {
        const fullPath = path.join(dirPath, item.name);
        
        if (item.isDirectory()) {
          await scanDirectory(fullPath);
        } else if (item.isFile() && item.name.endsWith('.js') && !item.name.includes('test')) {
          modules.push(fullPath);
        }
      }
    };
    
    await scanDirectory(this.LIB_PATH);
    return modules;
  }
  
  /**
   * 🎯 EXTRACTION MÉTHODES CLASSE - PARSER ORIENTÉ OBJET
   * 
   * CE QUI EST TESTÉ :
   * ✅ Extraction méthodes depuis position début classe
   * ✅ Support async methods avec pattern flexible
   * ✅ Exclusion constructor (pas testé automatiquement)
   * ✅ Return array noms méthodes pour tests génération
   * 
   * ALGORITHME EXÉCUTÉ :
   * - substring(classStartIndex) pour focus contenu classe
   * - Pattern : /(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{/g
   * - Filter !== 'constructor' pour méthodes publiques
   * - Return methods array pour class analysis
   */
  static extractClassMethods(content, classStartIndex) {
    // Extraction simplifiée des méthodes de classe
    const methods = [];
    const classContent = content.substring(classStartIndex);
    const methodPattern = /(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{/g;
    
    let match;
    while ((match = methodPattern.exec(classContent)) !== null) {
      if (match[1] !== 'constructor') {
        methods.push(match[1]);
      }
    }
    
    return methods;
  }
  
  /**
   * 📤 GÉNÉRATION TEST EXPORT - VÉRIFICATEUR INTERFACE
   * 
   * CE QUI EST TESTÉ :
   * ✅ Vérification disponibilité export (!== undefined)
   * ✅ Test simple existence pour interface module
   * ✅ Logging success pour debugging
   * ✅ Structure test object standardisée
   * 
   * ALGORITHME EXÉCUTÉ :
   * - Assert moduleName.exportName !== undefined
   * - Template minimal avec console.log success
   * - Return test object avec name, type:'export', template, exportName
   */
  static generateExportTest(exportName, analysis) {
    return {
      name: `export_${exportName}_test`,
      type: 'export',
      template: `
  test('Export - ${exportName}', () => {
    assert.ok(${analysis.moduleName}.${exportName} !== undefined, 'Export ${exportName} should be available');
    console.log('✅ Export ${exportName}: Available');
  });`,
      exportName
    };
  }
  
  static generateIntegrationTest(analysis) {
    return {
      name: 'integration_test',
      type: 'integration',
      template: '', // Géré dans buildTestFileContent
      analysis
    };
  }
  
  /**
   * 🎨 GÉNÉRATION MASTER TEST RUNNER - ORCHESTRATEUR GLOBAL
   * 
   * CE QUI EST TESTÉ :
   * ✅ Création runner exécutant tous tests générés en séquence
   * ✅ Gestion spawn Node.js avec --test flag pour chaque fichier
   * ✅ Comptage passed/failed avec exit code approprié
   * ✅ Logging détaillé pour monitoring execution
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Génération TEST_FILES array depuis moduleResults paths
   * - runSingleTest() avec spawn('node', ['--test', testPath])
   * - Promise wrapper pour child process avec close/error events
   * - Stats tracking + process.exit(1) si failures
   */
  static async generateMasterTestRunner(moduleResults) {
    const runnerPath = path.join(this.GENERATED_TESTS_PATH, 'test-runner-generated.js');
    
    const runnerContent = `// ========================================
// RUNNER TESTS GÉNÉRÉS AUTOMATIQUEMENT
// Exécute tous les tests générés pour les modules lib/
// ========================================

const { spawn } = require('child_process');
const path = require('path');

const TEST_FILES = [
${moduleResults.map(r => `  '${path.basename(r.testFilePath)}'`).join(',\n')}
];

async function runGeneratedTests() {
  console.log('🧪 === TESTS GÉNÉRÉS AUTOMATIQUEMENT ===');
  console.log(\`📦 \${TEST_FILES.length} fichiers de test détectés\`);
  
  let passed = 0;
  let failed = 0;
  
  for (const testFile of TEST_FILES) {
    console.log(\`\n🔍 Test: \${testFile}\`);
    
    try {
      await runSingleTest(testFile);
      passed++;
      console.log(\`✅ \${testFile}: PASSED\`);
    } catch (error) {
      failed++;
      console.log(\`❌ \${testFile}: FAILED - \${error.message}\`);
    }
  }
  
  console.log(\`\n📊 RÉSULTATS: \${passed} passed, \${failed} failed\`);
  
  if (failed > 0) {
    process.exit(1);
  }
}

function runSingleTest(testFile) {
  return new Promise((resolve, reject) => {
    const testPath = path.join(__dirname, testFile);
    const child = spawn('node', ['--test', testPath], {
      stdio: 'inherit'
    });
    
    child.on('close', (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(\`Test failed with code \${code}\`));
      }
    });
    
    child.on('error', reject);
  });
}

// Exécution si appelé directement
if (require.main === module) {
  runGeneratedTests().catch(error => {
    console.error('💥 Erreur runner:', error.message);
    process.exit(1);
  });
}

module.exports = { runGeneratedTests };`;
    
    await fs.writeFile(runnerPath, runnerContent, 'utf8');
    logSh(`📝 Test runner généré: ${runnerPath}`, 'DEBUG');
  }
}

module.exports = { ModuleTestGenerator };