const fs = require('fs');
const path = require('path');

const STATE_SERVICES_REGEX = /(redis|postgres|mysql|mongo|kafka|sqs|rabbit|elasticsearch|cassandra|db|cache|queue|database|aurora)/;

/**
 * Dynamically extract system configurations and state boundaries using generic heuristics.
 * Replaces extract-deep.js and extract-patterns.js.
 * This MUST be deterministic (no LLM calls).
 */
function extractDynamic(graph, archetype, repoRoot) {
  const result = {
    configs: [],
    stateServices: [],
    deploymentPatterns: [],
    networkTopology: []
  };

  if (!graph) return result;

  const files = graph.files || [];
  const entities = graph.entities || {};

  // 1. Config Surfaces (find generic config structures: Helm, JSON, YAML)
  const configFiles = files.filter(f => f.match(/\.(yaml|yml|json|toml|ini)$/i));
  
  // Extract a sample of configs deterministically from generic entities
  for (const [id, entity] of Object.entries(entities)) {
    if (entity.type && (entity.type.includes('Config') || entity.type.includes('Params') || entity.type.includes('HelmValues'))) {
      result.configs.push({ name: entity.name, file: entity.file, type: entity.type });
    }
    
    // 2. State Services (databases, caches, queues)
    const lowerName = entity.name ? entity.name.toLowerCase() : '';
    if (lowerName.match(STATE_SERVICES_REGEX)) {
      if (!result.stateServices.some(s => s.name === entity.name)) {
        result.stateServices.push({ name: entity.name, type: entity.type || 'State/Database' });
      }
    }

    // 4. Network Topology (if infra archetype)
    if (archetype.toLowerCase().includes('infra')) {
      if (lowerName.includes('vpc') || lowerName.includes('cidr') || lowerName.includes('subnet') || lowerName.includes('route') || lowerName.includes('nat')) {
        result.networkTopology.push({ name: entity.name, file: entity.file, type: 'Network Resource' });
      }
    }
  }

  // Look for imports or dependencies that match state services
  if (graph.dependencies) {
    for (const dep of Object.keys(graph.dependencies)) {
      const lowerDep = dep.toLowerCase();
      if (lowerDep.match(STATE_SERVICES_REGEX)) {
        if (!result.stateServices.some(s => s.name === dep)) {
          result.stateServices.push({ name: dep, type: 'External Dependency' });
        }
      }
    }
  }

  // Look at package.json dependencies for state services
  try {
    const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
    const deps = Object.keys(pkg.dependencies || {});
    for (const dep of deps) {
      if (dep.match(STATE_SERVICES_REGEX)) {
         if (!result.stateServices.some(s => s.name === dep)) {
            result.stateServices.push({ name: dep, type: 'NPM Dependency' });
         }
      }
    }
  } catch (e) {
    console.warn('Failed to parse package.json for state services:', e.message);
  }

  // 3. Deployment Patterns (CI/CD, GitOps)
  const ciFiles = files.filter(f => f.match(/(\.github\/workflows|jenkinsfile|\.gitlab-ci|argocd|kustomization|dockerfile|helm)/i));
  for (const cf of ciFiles) {
    let type = 'CI/CD';
    if (cf.toLowerCase().includes('argocd')) type = 'GitOps';
    if (cf.toLowerCase().includes('helm')) type = 'Helm Chart';
    result.deploymentPatterns.push({ file: cf, type });
  }

  // Graceful fallback for config files if no config entities were found
  if (result.configs.length === 0) {
    for (const cf of configFiles.slice(0, 10)) {
      result.configs.push({ file: cf, type: 'Configuration File' });
    }
  }

  return result;
}

module.exports = { extractDynamic };
