#!/usr/bin/env node
/**
 * Orchestrator - Main Integration Point
 * 
 * Ties together: Pipeline → Router → LLM → Validator → Format Locker
 */

const ContextPipeline = require('./pipeline');
const WorkflowRouter = require('./workflow-router');
const ResponseValidator = require('./validator');
const FormatLocker = require('./format-locker');

class AgentOrchestrator {
  constructor(options = {}) {
    this.workspace = options.workspace || '/home/jcbeasley/.openclaw/workspace';
    this.verbose = options.verbose || false;
    this.autoFix = options.autoFix !== false;
    
    this.pipeline = new ContextPipeline();
    this.router = new WorkflowRouter();
  }

  /**
   * Main entry point - process user request through full pipeline
   */
  async process(userInput, context = {}) {
    const startTime = Date.now();
    
    this.log('=== Starting Orchestration ===');
    this.log(`Input: ${userInput.substring(0, 100)}...`);

    try {
      // Step 1: Build context
      this.log('Step 1: Building context...');
      const contextPacket = await this.buildContext(userInput, context);

      // Step 2: Classify intent and route
      this.log('Step 2: Classifying intent...');
      const route = this.router.route(userInput, context);

      // Step 3: Prepare system prompt
      this.log(`Step 3: Workflow = ${route.workflow} (${(route.confidence * 100).toFixed(1)}% confidence)`);
      const systemPrompt = this.buildSystemPrompt(route, contextPacket);

      // Step 4: Get response (this would call LLM)
      // For now, return the prompt for testing
      const response = {
        systemPrompt: systemPrompt,
        workflow: route.workflow,
        confidence: route.confidence,
        context: contextPacket
      };

      // Step 5: Validate response
      this.log('Step 4: Validating...');
      const validation = this.validateResponse(response.systemPrompt, route.workflow);

      // Step 6: Enforce format
      this.log('Step 5: Enforcing format...');
      const formatted = this.enforceFormat(response.systemPrompt, route.workflow);

      const duration = Date.now() - startTime;
      this.log(`=== Complete in ${duration}ms ===`);

      return {
        ...response,
        validation: validation,
        format: formatted,
        metadata: {
          duration: duration,
          timestamp: new Date().toISOString()
        }
      };

    } catch (error) {
      console.error('Orchestration error:', error);
      return {
        error: error.message,
        input: userInput,
        metadata: {
          duration: Date.now() - startTime,
          timestamp: new Date().toISOString()
        }
      };
    }
  }

  /**
   * Build context packet from all sources
   */
  async buildContext(userInput, context) {
    // Load rules
    await this.pipeline.loadRules();
    
    // Load preferences
    await this.pipeline.loadPreferences();
    
    // Load relevant memory
    await this.pipeline.loadRelevantMemory(userInput, 5);
    
    // Build final packet
    const packet = this.pipeline.buildPacket(userInput);
    
    // Add session context
    packet.project = context.project || process.env.CURRENT_PROJECT;
    packet.user = context.user || 'JC';
    
    return packet;
  }

  /**
   * Build combined system prompt
   */
  buildSystemPrompt(route, contextPacket) {
    const parts = [
      '# System Instructions',
      '',
      contextPacket.system,
      '',
      '---',
      '',
      '# Workflow Mode',
      route.systemPrompt,
      '',
      '---',
      '',
      '# Current Context',
      `Project: ${contextPacket.project || 'None'}`,
      `User: ${contextPacket.user || 'Unknown'}`,
      '',
      '---',
      '',
      '# Memory',
      contextPacket.memory.substring(0, 1000) // Truncate for brevity
    ];

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

  /**
   * Validate response against rules
   */
  validateResponse(response, workflow) {
    const validator = new ResponseValidator(workflow);
    return validator.validate(response);
  }

  /**
   * Enforce format compliance
   */
  enforceFormat(response, workflow) {
    const locker = new FormatLocker(workflow);
    return locker.enforceFormat(response, this.autoFix);
  }

  /**
   * Get format prompt for LLM
   */
  getFormatPrompt(workflow) {
    const locker = new FormatLocker(workflow);
    return locker.getFormatPrompt();
  }

  /**
   * Log with verbosity control
   */
  log(message) {
    if (this.verbose) {
      console.log(message);
    }
  }

  /**
   * Quick classification without full processing
   */
  classify(userInput) {
    return this.router.classifyIntent(userInput);
  }

  /**
   * Get workflow config
   */
  getWorkflow(name) {
    return this.router.getWorkflow(name);
  }
}

// Export for use
module.exports = AgentOrchestrator;

// CLI usage
if (require.main === module) {
  const userInput = process.argv[2] || 'implement a new feature';
  const verbose = process.argv.includes('--verbose') || process.argv.includes('-v');
  
  const orchestrator = new AgentOrchestrator({ verbose: verbose });
  
  orchestrator.process(userInput, { project: process.env.CURRENT_PROJECT })
    .then(result => {
      console.log(JSON.stringify(result, null, 2));
    })
    .catch(err => {
      console.error('Error:', err);
      process.exit(1);
    });
}
