/**
 * workflow-validation.test.js - Integration tests for workflows
 * Part of LCBP3-DMS Phase 3 enhancements
 */

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

// Test configuration
const BASE_DIR = path.resolve(__dirname, '..');
const WORKFLOWS_DIR = path.join(BASE_DIR, '.windsurf', 'workflows');
const AGENTS_DIR = path.join(BASE_DIR, '.agents');

// Test utilities
class WorkflowTestSuite {
  constructor() {
    this.results = {
      passed: 0,
      failed: 0,
      errors: [],
    };
  }

  log(message, type = 'info') {
    const colors = {
      info: '\x1b[36m', // Cyan
      pass: '\x1b[32m', // Green
      fail: '\x1b[31m', // Red
      warn: '\x1b[33m', // Yellow
      reset: '\x1b[0m',
    };

    const color = colors[type] || colors.info;
    console.log(`${color}${message}${colors.reset}`);
  }

  assert(condition, message) {
    if (condition) {
      this.log(`  PASS: ${message}`, 'pass');
      this.results.passed++;
      return true;
    } else {
      this.log(`  FAIL: ${message}`, 'fail');
      this.results.failed++;
      this.results.errors.push(message);
      return false;
    }
  }

  testWorkflowFile(filePath, expectedName) {
    if (!fs.existsSync(filePath)) {
      this.assert(false, `Workflow file exists: ${expectedName}`);
      return false;
    }

    try {
      const content = fs.readFileSync(filePath, 'utf8');

      // Basic structure checks
      this.assert(content.length > 0, `${expectedName} has content`);
      this.assert(content.includes('#'), `${expectedName} has markdown headers`);

      // Check for workflow-specific patterns
      if (expectedName.includes('speckit-')) {
        this.assert(content.includes('speckit-'), `${expectedName} contains speckit reference`);
      }

      // Check for proper markdown formatting
      const lines = content.split('\n');
      const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
      this.assert(nonEmptyLines.length >= 5, `${expectedName} has sufficient content`);

      return true;
    } catch (error) {
      this.assert(false, `${expectedName} - error reading file: ${error.message}`);
      return false;
    }
  }

  validateWorkflowDependency(workflowName, workflowContent) {
    // Check if workflow references existing skills
    const skillReferences = workflowContent.match(/@speckit-\w+/g) || [];
    const skillsDir = path.join(AGENTS_DIR, 'skills');

    for (const skillRef of skillReferences) {
      const skillName = skillRef.replace('@', '');
      const skillPath = path.join(skillsDir, skillName);

      if (!fs.existsSync(skillPath)) {
        this.assert(false, `${workflowName} references non-existent skill: ${skillRef}`);
        return false;
      }
    }

    return true;
  }
}

// Expected workflows mapping
const expectedWorkflows = {
  '00-speckit.all.md': 'Full pipeline workflow',
  '01-speckit.constitution.md': 'Constitution workflow',
  '02-speckit.specify.md': 'Specification workflow',
  '03-speckit.clarify.md': 'Clarification workflow',
  '04-speckit.plan.md': 'Planning workflow',
  '05-speckit.tasks.md': 'Task breakdown workflow',
  '06-speckit.analyze.md': 'Analysis workflow',
  '07-speckit.implement.md': 'Implementation workflow',
  '08-speckit.checker.md': 'Static analysis workflow',
  '09-speckit.tester.md': 'Testing workflow',
  '10-speckit.reviewer.md': 'Code review workflow',
  '11-speckit.validate.md': 'Validation workflow',
  'speckit.prepare.md': 'Preparation workflow',
  'schema-change.md': 'Schema change workflow',
  'create-backend-module.md': 'Backend module creation',
  'create-frontend-page.md': 'Frontend page creation',
  'deploy.md': 'Deployment workflow',
  'review.md': 'Code review workflow',
  'util-speckit.checklist.md': 'Checklist utility',
  'util-speckit.diff.md': 'Diff utility',
  'util-speckit.migrate.md': 'Migration utility',
  'util-speckit.quizme.md': 'Quiz utility',
  'util-speckit.status.md': 'Status utility',
  'util-speckit.taskstoissues.md': 'Task to issues utility',
};

// Test suite implementation
const workflowTestSuite = new WorkflowTestSuite();

function runWorkflowTests() {
  workflowTestSuite.log('=== Workflow Validation Test Suite ===', 'info');
  workflowTestSuite.log(`Workflows directory: ${WORKFLOWS_DIR}`, 'info');
  workflowTestSuite.log(`Started: ${new Date().toISOString()}`, 'info');
  workflowTestSuite.log('');

  // Test 1: Workflows directory exists
  workflowTestSuite.log('Test 1: Directory Structure', 'info');
  workflowTestSuite.assert(fs.existsSync(WORKFLOWS_DIR), 'Workflows directory exists');
  workflowTestSuite.log('');

  // Test 2: Expected workflow files exist
  workflowTestSuite.log('Test 2: Expected Workflow Files', 'info');
  let foundWorkflows = 0;

  for (const [filename, description] of Object.entries(expectedWorkflows)) {
    const filePath = path.join(WORKFLOWS_DIR, filename);
    workflowTestSuite.testWorkflowFile(filePath, description);
    if (fs.existsSync(filePath)) {
      foundWorkflows++;
    }
  }

  workflowTestSuite.assert(foundWorkflows >= 20, `Found at least 20 workflows (found ${foundWorkflows})`);
  workflowTestSuite.log('');

  // Test 3: Workflow content validation
  workflowTestSuite.log('Test 3: Content Validation', 'info');

  for (const [filename, description] of Object.entries(expectedWorkflows)) {
    const filePath = path.join(WORKFLOWS_DIR, filename);

    if (fs.existsSync(filePath)) {
      try {
        const content = fs.readFileSync(filePath, 'utf8');

        // Check for proper workflow structure
        workflowTestSuite.assert(content.includes('#'), `${filename} has markdown headers`);
        workflowTestSuite.assert(content.length > 100, `${filename} has substantial content`);

        // Validate skill dependencies
        workflowTestSuite.validateWorkflowDependency(filename, content);
      } catch (error) {
        workflowTestSuite.assert(false, `${filename} - content validation error: ${error.message}`);
      }
    }
  }
  workflowTestSuite.log('');

  // Test 4: Workflow naming consistency
  workflowTestSuite.log('Test 4: Naming Consistency', 'info');
  const actualFiles = fs.readdirSync(WORKFLOWS_DIR).filter((file) => file.endsWith('.md'));

  for (const actualFile of actualFiles) {
    if (!expectedWorkflows[actualFile]) {
      workflowTestSuite.log(`  UNEXPECTED: ${actualFile} not in expected list`, 'warn');
    }
  }

  for (const expectedFile of Object.keys(expectedWorkflows)) {
    if (!actualFiles.includes(expectedFile)) {
      workflowTestSuite.assert(false, `Missing expected workflow: ${expectedFile}`);
    }
  }
  workflowTestSuite.log('');

  // Test 5: Cross-reference validation
  workflowTestSuite.log('Test 5: Cross-Reference Validation', 'info');

  // Check if README.md references workflows correctly
  const readmePath = path.join(AGENTS_DIR, 'README.md');
  if (fs.existsSync(readmePath)) {
    const readmeContent = fs.readFileSync(readmePath, 'utf8');
    workflowTestSuite.assert(
      readmeContent.includes('.windsurf/workflows'),
      'README.md references correct workflows path'
    );
  }
  workflowTestSuite.log('');

  // Results Summary
  workflowTestSuite.log('=== Workflow Test Results Summary ===', 'info');
  workflowTestSuite.log(`Passed: ${workflowTestSuite.results.passed}`, 'pass');
  workflowTestSuite.log(
    `Failed: ${workflowTestSuite.results.failed}`,
    workflowTestSuite.results.failed > 0 ? 'fail' : 'pass'
  );

  if (workflowTestSuite.results.errors.length > 0) {
    workflowTestSuite.log('Errors:', 'fail');
    workflowTestSuite.results.errors.forEach((error) => {
      workflowTestSuite.log(`  - ${error}`, 'fail');
    });
  }

  workflowTestSuite.log(`Completed: ${new Date().toISOString()}`, 'info');

  return workflowTestSuite.results.failed === 0;
}

// Export for use in other modules
module.exports = { WorkflowTestSuite, runWorkflowTests };

// Run tests if called directly
if (require.main === module) {
  const success = runWorkflowTests();
  process.exit(success ? 0 : 1);
}
