#!/usr/bin/env node
/**
 * Workflow Router - Intent Classification and Routing
 * 
 * Before responding, classify intent and route to fixed workflow template
 */

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

class WorkflowRouter {
  constructor() {
    this.workflows = new Map();
    this.loadWorkflows();
  }

  /**
   * Load all workflow definitions from workflows/ directory
   */
  loadWorkflows() {
    const workflowsDir = path.join(__dirname, '..', 'workflows');
    
    const workflowFiles = [
      'coding.md',
      'debug.md', 
      'deploy.md',
      'audit.md',
      'planning.md'
    ];

    for (const file of workflowFiles) {
      const workflowName = path.basename(file, '.md');
      const filePath = path.join(workflowsDir, file);
      
      try {
        const content = fs.readFileSync(filePath, 'utf8');
        this.workflows.set(workflowName, this.parseWorkflow(content));
      } catch (err) {
        console.warn(`Workflow ${file} not found, using defaults`);
        this.workflows.set(workflowName, this.getDefaultWorkflow(workflowName));
      }
    }
  }

  /**
   * Parse workflow markdown into structured object
   */
  parseWorkflow(content) {
    const workflow = {
      name: '',
      triggers: [],
      outputFormat: '',
      toolRules: [],
      constraints: [],
      requiredSections: []
    };

    // Extract name from first header
    const nameMatch = content.match(/^#\s+Workflow:\s*(.+)$/m);
    if (nameMatch) workflow.name = nameMatch[1].trim();

    // Extract triggers
    const triggersMatch = content.match(/\*\*Triggers:\*\*\s*(.+)/);
    if (triggersMatch) {
      workflow.triggers = triggersMatch[1].split(',').map(t => t.trim().toLowerCase());
    }

    // Extract output format (code block after "Fixed Output Format")
    const formatMatch = content.match(/## Fixed Output Format\s*```markdown\s*([\s\S]*?)```/);
    if (formatMatch) workflow.outputFormat = formatMatch[1].trim();

    // Extract tool rules
    const rulesSection = content.match(/## Tool Access Rules\s*([\s\S]*?)(?=##|$)/);
    if (rulesSection) {
      workflow.toolRules = rulesSection[1]
        .split('\n')
        .filter(line => /^\d+\./.test(line))
        .map(line => line.replace(/^\d+\.\s*/, '').trim());
    }

    // Extract constraints
    const constraintsSection = content.match(/## Constraints\s*([\s\S]*?)(?=##|$)/);
    if (constraintsSection) {
      workflow.constraints = constraintsSection[1]
        .split('\n')
        .filter(line => /^(NO|YES):/.test(line))
        .map(line => line.trim());
    }

    // Extract required sections from format template
    const sectionMatches = workflow.outputFormat.match(/^##\s+(.+)$/gm);
    if (sectionMatches) {
      workflow.requiredSections = sectionMatches.map(s => s.replace(/^##\s*/, '').trim());
    }

    return workflow;
  }

  /**
   * Classify user intent and return matching workflow
   */
  classifyIntent(userInput) {
    const input = userInput.toLowerCase();
    
    // Intent patterns with confidence scoring
    const intentPatterns = {
      'coding': {
        patterns: [
          /\b(code|implement|build|create|write|develop|feature|fix bug|add\s+\w+\s+to)\b/,
          /\b(refactor|optimize|improve|clean up)\b/,
          /\b(pull request|pr|commit|merge|branch)\b/,
          /\b(api|endpoint|route|handler|controller|model)\b/
        ],
        weight: 1.0
      },
      'debug': {
        patterns: [
          /\b(debug|fix|broken|error|bug|issue|problem|crash|fails?|not working)\b/,
          /\b(troubleshoot|diagnose|investigate|trace|root cause)\b/,
          /\b(exception|stack trace|log|error message)\b/
        ],
        weight: 1.0
      },
      'deploy': {
        patterns: [
          /\b(deploy|release|push to|go live|production|staging)\b/,
          /\b(docker|container|build|image|registry)\b/,
          /\b(rollback|revert|restore|emergency)\b/,
          /\b(install|upgrade|update|migrate)\b/
        ],
        weight: 1.0
      },
      'audit': {
        patterns: [
          /\b(audit|review|assess|inventory|check|scan|inspect)\b/,
          /\b(security|vulnerability|compliance|policy)\b/,
          /\b(status|health|state|report|summary)\b/,
          /\b(workspace|files|structure|organization)\b/
        ],
        weight: 1.0
      },
      'planning': {
        patterns: [
          /\b(plan|design|architecture|strategy|roadmap|timeline)\b/,
          /\b(requirement|spec|proposal|approach)\b/,
          /\b(breakdown|estimate|scope|prioritize)\b/
        ],
        weight: 0.8
      }
    };

    let bestMatch = null;
    let bestScore = 0;

    for (const [workflowName, config] of Object.entries(intentPatterns)) {
      let score = 0;
      let matches = 0;
      
      for (const pattern of config.patterns) {
        if (pattern.test(input)) {
          matches++;
          score += config.weight;
        }
      }

      // Boost score for multiple matches
      if (matches > 1) score *= 1.2;

      if (score > bestScore) {
        bestScore = score;
        bestMatch = workflowName;
      }
    }

    // Default to coding if no strong match
    if (bestScore < 0.5 || !bestMatch) {
      bestMatch = 'coding';
      bestScore = 0.3;
    }

    return {
      workflow: bestMatch,
      confidence: Math.min(bestScore / 2, 1.0), // Normalize
      allScores: this.getAllScores(intentPatterns, input)
    };
  }

  /**
   * Get confidence scores for all workflows
   */
  getAllScores(patterns, input) {
    const scores = {};
    for (const [name, config] of Object.entries(patterns)) {
      let score = 0;
      for (const pattern of config.patterns) {
        if (pattern.test(input)) score += config.weight;
      }
      scores[name] = score;
    }
    return scores;
  }

  /**
   * Get workflow by name
   */
  getWorkflow(name) {
    return this.workflows.get(name) || this.getDefaultWorkflow(name);
  }

  /**
   * Get default workflow template
   */
  getDefaultWorkflow(name) {
    return {
      name: name || 'default',
      triggers: ['general'],
      outputFormat: '## Summary\n[Response]\n\n## Details\n[Details]',
      toolRules: ['Delegate when possible', 'Verify before reporting'],
      constraints: ['NO: Assumptions without verification', 'YES: Clear status updates'],
      requiredSections: ['Summary', 'Details']
    };
  }

  /**
   * Build context-aware system prompt for the classified workflow
   */
  buildSystemPrompt(workflowName, context = {}) {
    const workflow = this.getWorkflow(workflowName);
    
    const parts = [
      `You are in ${workflow.name} workflow mode.`,
      '',
      '## Required Output Sections',
      ...workflow.requiredSections.map(s => `- ${s}`),
      '',
      '## Tool Access Rules',
      ...workflow.toolRules.map((rule, i) => `${i + 1}. ${rule}`),
      '',
      '## Constraints',
      ...workflow.constraints,
      '',
      '## Format Template',
      '```markdown',
      workflow.outputFormat,
      '```'
    ];

    if (context.project) {
      parts.push('', `## Current Project: ${context.project}`);
    }

    return parts.join('\n');
  }

  /**
   * Main entry point: classify and route
   */
  route(userInput, context = {}) {
    const classification = this.classifyIntent(userInput);
    const workflow = this.getWorkflow(classification.workflow);
    const systemPrompt = this.buildSystemPrompt(classification.workflow, context);

    return {
      workflow: classification.workflow,
      confidence: classification.confidence,
      workflowConfig: workflow,
      systemPrompt: systemPrompt,
      context: context
    };
  }
}

// Export for use
module.exports = WorkflowRouter;

// CLI usage
if (require.main === module) {
  const router = new WorkflowRouter();
  const userInput = process.argv[2] || 'implement a new feature';
  
  const result = router.route(userInput, { project: process.env.CURRENT_PROJECT });
  
  console.log('=== Workflow Classification ===');
  console.log(`Workflow: ${result.workflow}`);
  console.log(`Confidence: ${(result.confidence * 100).toFixed(1)}%`);
  console.log('\n=== System Prompt ===');
  console.log(result.systemPrompt);
}
