# Generator Framework

The Bangstack generator framework provides a pluggable system for generating code from workflow definitions.

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                      Code Generator                         │
│  (Orchestrates generation from workflows)                   │
└──────────────────────┬──────────────────────────────────────┘
                       │
         ┌─────────────┼─────────────┐
         │             │             │
         ▼             ▼             ▼
  ┌───────────┐ ┌───────────┐ ┌───────────┐
  │ Frontend  │ │ Backend   │ │   Docs    │
  │ Generator │ │ Generator │ │ Generator │
  └───────────┘ └───────────┘ └───────────┘
         │             │             │
         └─────────────┼─────────────┘
                       │
                       ▼
              ┌────────────────┐
              │  File Writer   │
              └────────────────┘
                       │
                       ▼
              Generated Files
```

## Core Components

### 1. Generator Interface

All generators implement the base `Generator` interface:

```typescript
interface Generator {
  id: string;
  name: string;
  description: string;
  generate(context: GeneratorContext): Promise<GenerationResult> | GenerationResult;
}
```

Specialized generator types:
- `FrontendGenerator` - for UI frameworks (React, Vue, Angular)
- `BackendGenerator` - for API frameworks (Express, Fastify, Go, Python)
- `DocumentationGenerator` - for docs (Markdown, HTML, PDF)
- `DatabaseGenerator` - for migrations (PostgreSQL, MySQL, MongoDB)
- `TestGenerator` - for test frameworks (Jest, Mocha, Pytest)

### 2. Generator Registry

Manages available generators and provides lookup:

```typescript
const registry = new GeneratorRegistry();

// Register generators
registry.registerFrontendGenerator(reactGenerator);
registry.registerBackendGenerator(typescriptExpressGenerator);

// Retrieve generators
const reactGen = registry.getFrontendGenerator('react');
const tsGen = registry.getBackendGenerator('typescript', 'express');
```

Features:
- Type-safe generator registration
- Framework-specific lookup
- Fallback to default implementations
- List available generators

### 3. Code Generator

Orchestrates code generation from workflows:

```typescript
const generator = new CodeGenerator();

const result = await generator.generate(workflow, {
  outputDirectory: './output',
  dryRun: false,
  verbose: true,
});

console.log(`Generated ${result.files.length} files`);
console.log(`Wrote: ${result.written.join(', ')}`);
```

Process:
1. Validates workflow
2. Analyzes workflow (creates execution plan)
3. Calls appropriate generators based on workflow config
4. Writes generated files to disk

### 4. File Writer

Handles writing generated files:

```typescript
const writer = new FileWriter();

await writer.write(files, {
  dryRun: false,
  verbose: true,
});
```

Features:
- Dry run mode (preview without writing)
- Overwrite control per file
- Preserve mode for manual edits (future)
- Verbose logging

## Generator Context

All generators receive a `GeneratorContext`:

```typescript
interface GeneratorContext {
  workflow: Workflow;           // The workflow definition
  executionPlan: ExecutionPlan; // Analyzed execution plan
  outputDirectory: string;       // Where to write files
  options?: GeneratorOptions;    // Custom options
}
```

The execution plan includes:
- DAG of frontend action steps
- DAG of backend implementation steps
- Entry/exit points
- Execution levels (parallelizable steps)

## Creating a Generator

### Example: Simple Frontend Generator

```typescript
import { FrontendGenerator, GeneratorContext, GenerationResult } from 'bangstack';

class MyFrameworkGenerator implements FrontendGenerator {
  id = 'my-framework';
  name = 'My Framework Generator';
  description = 'Generates code for My Framework';
  framework = 'my-framework';

  generate(context: GeneratorContext): GenerationResult {
    const { workflow, executionPlan } = context;
    const files = [];

    // Generate components
    if (workflow.frontend?.components) {
      for (const component of workflow.frontend.components) {
        files.push({
          path: `src/components/${component.name}.tsx`,
          content: this.generateComponent(component),
          overwrite: true,
        });
      }
    }

    return { files };
  }

  private generateComponent(component: Component): string {
    return `
      // Generated component: ${component.name}
      export function ${component.name}() {
        return <div>${component.description}</div>;
      }
    `;
  }
}

// Register the generator
import { globalRegistry } from 'bangstack';
globalRegistry.registerFrontendGenerator(new MyFrameworkGenerator());
```

### Example: Backend Generator

```typescript
class MyBackendGenerator implements BackendGenerator {
  id = 'my-backend';
  name = 'My Backend Generator';
  description = 'Generates backend API code';
  language = 'typescript';
  framework = 'express';

  generate(context: GeneratorContext): GenerationResult {
    const { workflow, executionPlan } = context;
    const files = [];

    // Generate endpoints
    if (workflow.backend?.endpoints) {
      for (const endpoint of workflow.backend.endpoints) {
        const implPlan = executionPlan.backendImplementations.get(endpoint.id);

        files.push({
          path: `src/api/${endpoint.id}.ts`,
          content: this.generateEndpoint(endpoint, implPlan),
          overwrite: true,
        });
      }
    }

    return { files };
  }

  private generateEndpoint(endpoint: Endpoint, plan: ImplementationExecutionPlan): string {
    // Use execution plan to generate properly ordered code
    const steps = plan.executionLevels.flat();

    return `
      // ${endpoint.method} ${endpoint.path}
      export async function ${endpoint.name}(req, res) {
        ${steps.map(step => this.generateStep(step)).join('\n')}
      }
    `;
  }

  private generateStep(step: Step): string {
    return `// Step: ${step.id} - ${step.action}`;
  }
}
```

## Using the DAG for Code Generation

The execution plan's DAG helps generate properly ordered code:

```typescript
// Get execution levels (steps that can run in parallel)
const levels = implPlan.executionLevels;

// Level 1: [validate-request]
// Level 2: [find-user]
// Level 3: [verify-password]
// etc.

// Generate sequential code from levels
for (const level of levels) {
  if (level.length === 1) {
    // Sequential step
    code += generateStep(level[0]);
  } else {
    // Parallel steps - use Promise.all
    code += `await Promise.all([
      ${level.map(step => generateStep(step)).join(',\n')}
    ]);`;
  }
}
```

## File Generation Patterns

### 1. Component-per-file

```typescript
for (const component of workflow.frontend.components) {
  files.push({
    path: `src/components/${component.name}.tsx`,
    content: generateComponent(component),
  });
}
```

### 2. Grouped by feature

```typescript
files.push({
  path: `src/features/${workflow.workflow.id}/index.ts`,
  content: generateFeature(workflow),
});
```

### 3. Barrel exports

```typescript
files.push({
  path: `src/components/index.ts`,
  content: components.map(c => `export { ${c.name} } from './${c.name}';`).join('\n'),
});
```

## Testing Generators

```typescript
describe('MyGenerator', () => {
  it('should generate components', () => {
    const generator = new MyGenerator();
    const context: GeneratorContext = {
      workflow: testWorkflow,
      executionPlan: mockExecutionPlan,
      outputDirectory: './output',
    };

    const result = generator.generate(context);

    expect(result.files.length).toBeGreaterThan(0);
    expect(result.files[0].path).toContain('components');
  });
});
```

## Best Practices

1. **Use execution plan for ordering** - Don't assume step order, use the DAG
2. **Generate idempotent code** - Same workflow → same generated code
3. **Provide helpful comments** - Explain what was generated and why
4. **Handle errors gracefully** - Return errors in GenerationResult
5. **Support dry run** - Don't write files in generate(), return them
6. **Respect overwrite flags** - Use preserve mode for customizable code
7. **Generate formatted code** - Use Prettier, gofmt, etc.
8. **Include tests** - Generate test files alongside implementation

## Future Enhancements

- **Template system** - Use Handlebars/EJS for complex templates
- **Incremental generation** - Only regenerate changed files
- **Smart merging** - Preserve manual edits in generated files
- **Source maps** - Map generated code back to workflow
- **Validation** - Lint/type-check generated code before writing
- **Plugins** - Allow generators to extend each other
