/**
 * Tests for WorkflowParser
 */

import { WorkflowParser } from './workflow-parser';
import * as path from 'path';

describe('WorkflowParser', () => {
  let parser: WorkflowParser;

  beforeEach(() => {
    parser = new WorkflowParser();
  });

  describe('parseFile', () => {
    it('should parse a valid workflow file', async () => {
      const workflowPath = path.join(__dirname, '../../examples/validatestack-mvp.workflow.yaml');
      const result = await parser.parseFile(workflowPath);

      expect(result).toBeDefined();
      expect(result.workflow).toBeDefined();
      expect((result.workflow.workflow as any).id).toBe('validatestack-mvp');
      expect((result.workflow.workflow as any).name).toBe('ValidateStack MVP');
      expect((result.workflow.workflow as any).version).toBe('1.0.0');
    });

    it('should throw error for non-existent file', async () => {
      await expect(parser.parseFile('non-existent.yaml')).rejects.toThrow('Workflow file not found');
    });
  });

  describe('parseString', () => {
    it('should parse a valid minimal workflow', async () => {
      const yamlContent = `
workflow:
  id: test-workflow
  version: 1.0.0
  name: Test Workflow
  description: A test workflow

stack:
  web-app:
    type: frontend
    technology: react
    components:
      - id: test-component
        type: form-component
        name: TestComponent
        description: A test component
`;

      const result = await parser.parseString(yamlContent);

      expect(result).toBeDefined();
      expect(result.workflow).toBeDefined();
      expect((result.workflow.workflow as any).id).toBe('test-workflow');
      expect((result.workflow.workflow as any).name).toBe('Test Workflow');
      expect((result.workflow.stack as any)).toBeDefined();
      expect((result.workflow.stack as any)['web-app']).toBeDefined();
      expect((result.workflow.stack as any)['web-app'].type).toBe('frontend');
      expect((result.workflow.stack as any)['web-app'].technology).toBe('react');
    });

    it('should throw validation error for missing required fields', async () => {
      const yamlContent = `
workflow:
  id: test-workflow
  version: 1.0.0
`;

      await expect(parser.parseString(yamlContent)).rejects.toThrow('Validation error');
    });

    it('should throw error for empty workflow', async () => {
      await expect(parser.parseString('')).rejects.toThrow('Empty workflow file');
    });

    it('should throw error for workflow without any stack components', async () => {
      const yamlContent = `
workflow:
  id: test-workflow
  version: 1.0.0
  name: Test Workflow
  description: A test workflow
stack: {}
`;

      await expect(parser.parseString(yamlContent)).rejects.toThrow('Workflow must define at least one stack component');
    });
  });

  describe('parseDirectory', () => {
    it('should parse a known-good workflow file', async () => {
      // Test with a specific workflow file that we know works (no circular refs)
      const testDir = path.join(__dirname, '../../examples');
      const testFile = path.join(testDir, 'validatestack-mvp.workflow.yaml');

      // Just test that we can parse a single known-good workflow file
      const result = await parser.parseFile(testFile);

      expect(result).toBeDefined();
      expect(result.workflow).toBeDefined();
      expect((result.workflow.workflow as any).id).toBe('validatestack-mvp');
      expect((result.workflow.workflow as any).name).toBe('ValidateStack MVP');
    });

    it('should throw error for non-existent directory', async () => {
      await expect(parser.parseDirectory('non-existent-dir')).rejects.toThrow('Directory not found');
    });
  });
});
