/**
 * Tests for MarkdownDocumentationGenerator
 */

import { MarkdownDocumentationGenerator } from './markdown-generator';
import { WorkflowParser } from '../../parser/workflow-parser';
import { WorkflowEngine } from '../../engine/workflow-engine';
import * as path from 'path';

describe('MarkdownDocumentationGenerator', () => {
  let generator: MarkdownDocumentationGenerator;

  beforeEach(() => {
    generator = new MarkdownDocumentationGenerator();
  });

  it('should have correct metadata', () => {
    expect(generator.id).toBe('markdown-docs');
    expect(generator.name).toBe('Markdown Documentation Generator');
    expect(generator.format).toBe('markdown');
  });

  it('should generate empty result for workflow without documentation', async () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test workflow',
      },
      stack: {
        app: {
          type: 'frontend',
          technology: 'react',
        },
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = await generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    expect(result.files).toHaveLength(0);
  });

  it('should generate documentation from user-authentication workflow', async () => {
    const parser = new WorkflowParser();
    const workflowPath = path.join(__dirname, '../../../examples/user-authentication.workflow.yaml');
    const result = await parser.parseFile(workflowPath);

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(result.workflow);

    const genResult = await generator.generate({
      workflow: result.workflow,
      executionPlan,
      outputDirectory: '/test',
    });

    // Should generate files
    expect(genResult.files.length).toBeGreaterThan(0);

    // Should generate main README
    const mainReadme = genResult.files.find(f => f.path === '/test/docs/README.md');
    expect(mainReadme).toBeDefined();
    expect(mainReadme?.content).toContain('# User Authentication');
    expect(mainReadme?.content).toContain('## Stack Components');

    // Should generate user docs if they exist
    if (result.workflow.documentation?.user_docs) {
      const userReadme = genResult.files.find(f => f.path === '/test/docs/user/README.md');
      expect(userReadme).toBeDefined();
      expect(userReadme?.content).toContain('# User Documentation');
    }

    // Should generate developer docs if they exist
    if (result.workflow.documentation?.developer_docs) {
      const devReadme = genResult.files.find(f => f.path === '/test/docs/developer/README.md');
      expect(devReadme).toBeDefined();
      expect(devReadme?.content).toContain('# Developer Documentation');
    }
  });

  it('should generate user documentation files', async () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test Workflow',
        version: '1.0.0',
        description: 'Test workflow description',
      },
      stack: {
        app: {
          type: 'frontend',
          technology: 'react',
        },
      },
      documentation: {
        user_docs: [
          {
            title: 'Getting Started',
            sections: [
              {
                heading: 'Introduction',
                content: 'Welcome to the app',
                steps: ['Step 1', 'Step 2'],
                examples: [
                  {
                    language: 'javascript',
                    code: 'console.log("Hello");',
                  },
                ],
              },
            ],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = await generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    // Should generate user doc file
    const userDoc = result.files.find(f => f.path === '/test/docs/user/getting-started.md');
    expect(userDoc).toBeDefined();
    expect(userDoc?.content).toContain('# Getting Started');
    expect(userDoc?.content).toContain('## Introduction');
    expect(userDoc?.content).toContain('Welcome to the app');
    expect(userDoc?.content).toContain('### Steps');
    expect(userDoc?.content).toContain('1. Step 1');
    expect(userDoc?.content).toContain('### Examples');
    expect(userDoc?.content).toContain('```javascript');
    expect(userDoc?.content).toContain('console.log("Hello");');

    // Should generate user docs index
    const userIndex = result.files.find(f => f.path === '/test/docs/user/README.md');
    expect(userIndex).toBeDefined();
    expect(userIndex?.content).toContain('# User Documentation');
    expect(userIndex?.content).toContain('[Getting Started](./getting-started.md)');
  });

  it('should generate developer documentation files', async () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test Workflow',
        version: '1.0.0',
        description: 'Test workflow description',
      },
      stack: {
        api: {
          type: 'backend',
          technology: 'typescript/express',
        },
      },
      documentation: {
        developer_docs: [
          {
            title: 'API Reference',
            sections: [
              {
                heading: 'Authentication',
                content: 'How to authenticate',
                examples: [
                  {
                    language: 'typescript',
                    code: 'const token = getToken();',
                  },
                ],
              },
            ],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = await generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    // Should generate developer doc file
    const devDoc = result.files.find(f => f.path === '/test/docs/developer/api-reference.md');
    expect(devDoc).toBeDefined();
    expect(devDoc?.content).toContain('# API Reference');
    expect(devDoc?.content).toContain('## Authentication');
    expect(devDoc?.content).toContain('How to authenticate');
    expect(devDoc?.content).toContain('```typescript');

    // Should generate developer docs index
    const devIndex = result.files.find(f => f.path === '/test/docs/developer/README.md');
    expect(devIndex).toBeDefined();
    expect(devIndex?.content).toContain('# Developer Documentation');
    expect(devIndex?.content).toContain('[API Reference](./api-reference.md)');
  });

  it('should slugify titles correctly', async () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        app: {
          type: 'frontend',
          technology: 'react',
        },
      },
      documentation: {
        user_docs: [
          {
            title: 'Getting Started Guide!',
            sections: [
              {
                heading: 'Test',
                content: 'Test content',
              },
            ],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = await generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    // Should slugify the title
    const userDoc = result.files.find(f => f.path === '/test/docs/user/getting-started-guide.md');
    expect(userDoc).toBeDefined();
  });
});
