"use strict";
/**
 * Architecture Documentation Template
 * Generates system architecture documentation including components, data flow, and technology stack
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArchitectureTemplate = void 0;
const base_template_1 = require("./base-template");
class ArchitectureTemplate extends base_template_1.DocumentationTemplate {
    canHandle(intent) {
        return intent.type === 'architecture';
    }
    generate(context) {
        const { workflow, extendedWorkflow } = context;
        let content = `# Architecture Documentation\n\n`;
        if (workflow.workflow.description) {
            content += `${workflow.workflow.description}\n\n`;
        }
        // Overview section
        content += this.generateOverview(context);
        // Technology Stack
        content += this.generateTechnologyStack(context);
        // System Components
        if (extendedWorkflow?.components || workflow.stack) {
            content += this.generateComponents(context);
        }
        // Data Models
        if (extendedWorkflow?.models) {
            content += this.generateDataArchitecture(context);
        }
        // API Architecture
        if (extendedWorkflow?.api) {
            content += this.generateApiArchitecture(context);
        }
        // Data Flow
        if (extendedWorkflow?.workflows || extendedWorkflow?.events) {
            content += this.generateDataFlow(context);
        }
        // Deployment Architecture
        content += this.generateDeploymentArchitecture(context);
        // Security Architecture
        if (extendedWorkflow?.auth?.enabled) {
            content += this.generateSecurityArchitecture(context);
        }
        content += this.generateFooter(context);
        return content;
    }
    generateOverview(context) {
        const { workflow, extendedWorkflow } = context;
        let content = `## System Overview\n\n`;
        content += `**Application:** ${workflow.workflow.name}\n`;
        content += `**Version:** ${workflow.workflow.version}\n`;
        if (workflow.workflow.domains && workflow.workflow.domains.length > 0) {
            content += `**Domains:** ${workflow.workflow.domains.join(', ')}\n`;
        }
        content += '\n';
        // Architecture type
        const hasBackend = extendedWorkflow?.technology?.backend;
        const hasFrontend = extendedWorkflow?.technology?.frontend;
        if (hasBackend && hasFrontend) {
            content += `**Architecture Pattern:** Client-Server (Full-Stack)\n\n`;
            content += `This application follows a client-server architecture with a separate frontend and backend.\n\n`;
        }
        else if (hasBackend) {
            content += `**Architecture Pattern:** Backend/API\n\n`;
            content += `This application provides a backend API service.\n\n`;
        }
        else if (hasFrontend) {
            content += `**Architecture Pattern:** Frontend/SPA\n\n`;
            content += `This application is a single-page application (SPA).\n\n`;
        }
        return content;
    }
    generateTechnologyStack(context) {
        const { extendedWorkflow } = context;
        const tech = extendedWorkflow?.technology;
        if (!tech) {
            return '';
        }
        let content = `## Technology Stack\n\n`;
        // Frontend
        if (tech.frontend) {
            content += `### Frontend\n\n`;
            content += `- **Framework:** ${this.capitalize(tech.frontend.framework || 'Unknown')}\n`;
            if (tech.frontend.language) {
                content += `- **Language:** ${this.capitalize(tech.frontend.language)}\n`;
            }
            if (tech.frontend.styling) {
                content += `- **Styling:** ${this.capitalize(tech.frontend.styling)}\n`;
            }
            if (tech.frontend.state_management) {
                content += `- **State Management:** ${this.capitalize(tech.frontend.state_management)}\n`;
            }
            content += '\n';
        }
        // Backend
        if (tech.backend) {
            content += `### Backend\n\n`;
            content += `- **Framework:** ${this.capitalize(tech.backend.framework || 'Unknown')}\n`;
            if (tech.backend.language) {
                content += `- **Language:** ${this.capitalize(tech.backend.language)}\n`;
            }
            if (tech.backend.orm) {
                content += `- **ORM:** ${this.capitalize(tech.backend.orm)}\n`;
            }
            content += '\n';
        }
        // Database
        if (tech.database) {
            content += `### Database\n\n`;
            content += `- **Type:** ${this.capitalize(tech.database.type || 'Unknown')}\n`;
            if (tech.database.version) {
                content += `- **Version:** ${tech.database.version}\n`;
            }
            content += '\n';
        }
        // Authentication
        if (extendedWorkflow?.auth?.enabled) {
            content += `### Authentication\n\n`;
            content += `- **Provider:** ${this.capitalize(extendedWorkflow.auth.provider || 'Custom')}\n`;
            if (extendedWorkflow.auth.strategies) {
                content += `- **Strategies:** ${extendedWorkflow.auth.strategies.join(', ')}\n`;
            }
            content += '\n';
        }
        // Testing
        if (tech.testing) {
            content += `### Testing\n\n`;
            if (tech.testing.unit) {
                content += `- **Unit Tests:** ${this.capitalize(tech.testing.unit)}\n`;
            }
            if (tech.testing.e2e) {
                content += `- **E2E Tests:** ${this.capitalize(tech.testing.e2e)}\n`;
            }
            content += '\n';
        }
        return content;
    }
    generateComponents(context) {
        const { workflow, extendedWorkflow } = context;
        let content = `## System Components\n\n`;
        // Stack components
        if (workflow.stack && Object.keys(workflow.stack).length > 0) {
            content += `### Stack Components\n\n`;
            for (const [name, component] of Object.entries(workflow.stack)) {
                const comp = component;
                content += `#### ${this.capitalize(name)}\n\n`;
                content += `- **Type:** ${comp.type}\n`;
                content += `- **Technology:** ${comp.technology}\n`;
                if (comp.services && Object.keys(comp.services).length > 0) {
                    content += `- **Services:**\n`;
                    for (const [serviceName, service] of Object.entries(comp.services)) {
                        const svc = service;
                        content += `  - ${serviceName}: ${svc.type}\n`;
                    }
                }
                content += '\n';
            }
        }
        // Extended workflow components
        if (extendedWorkflow?.components && Object.keys(extendedWorkflow.components).length > 0) {
            content += `### Application Components\n\n`;
            for (const [name, component] of Object.entries(extendedWorkflow.components)) {
                const comp = component;
                content += `#### ${this.capitalize(name)}\n\n`;
                if (comp.description) {
                    content += `${comp.description}\n\n`;
                }
                if (comp.emits && comp.emits.length > 0) {
                    content += `**Emits Events:** ${comp.emits.join(', ')}\n\n`;
                }
                if (comp.consumes && comp.consumes.length > 0) {
                    content += `**Consumes Events:** ${comp.consumes.join(', ')}\n\n`;
                }
            }
        }
        return content;
    }
    generateDataArchitecture(context) {
        const { extendedWorkflow } = context;
        const models = extendedWorkflow?.models || {};
        let content = `## Data Architecture\n\n`;
        content += `### Entity Relationship Model\n\n`;
        if (Object.keys(models).length === 0) {
            content += `No data models defined.\n\n`;
            return content;
        }
        content += `The application uses the following data models:\n\n`;
        for (const [modelName, model] of Object.entries(models)) {
            const modelData = model;
            content += `#### ${modelName}\n\n`;
            if (modelData.description) {
                content += `${modelData.description}\n\n`;
            }
            // Count fields
            const fieldCount = Object.keys(modelData.fields || {}).length;
            content += `- **Fields:** ${fieldCount}\n`;
            if (modelData.timestamps !== false) {
                content += `- **Timestamps:** Enabled (created_at, updated_at)\n`;
            }
            if (modelData.soft_delete) {
                content += `- **Soft Delete:** Enabled\n`;
            }
            if (modelData.indexes && modelData.indexes.length > 0) {
                content += `- **Indexes:** ${modelData.indexes.length}\n`;
            }
            content += '\n';
        }
        // Relationships
        if (extendedWorkflow?.relationships && extendedWorkflow.relationships.length > 0) {
            content += `### Relationships\n\n`;
            content += '```\n';
            for (const rel of extendedWorkflow.relationships) {
                const arrow = rel.type === 'one_to_one' ? '1---1' :
                    rel.type === 'one_to_many' ? '1---*' :
                        rel.type === 'many_to_many' ? '*---*' : '---';
                content += `${rel.from} ${arrow} ${rel.to}\n`;
            }
            content += '```\n\n';
        }
        return content;
    }
    generateApiArchitecture(context) {
        const { extendedWorkflow } = context;
        const api = extendedWorkflow?.api;
        if (!api) {
            return '';
        }
        let content = `## API Architecture\n\n`;
        content += `### RESTful API\n\n`;
        content += `**Base Path:** \`${api.base_path || '/api'}\`\n\n`;
        if (api.endpoints && api.endpoints.length > 0) {
            content += `**Total Endpoints:** ${api.endpoints.length}\n\n`;
            // Group by HTTP method
            const methodCounts = {};
            for (const endpoint of api.endpoints) {
                methodCounts[endpoint.method] = (methodCounts[endpoint.method] || 0) + 1;
            }
            content += `**Endpoints by Method:**\n`;
            for (const [method, count] of Object.entries(methodCounts)) {
                content += `- ${method}: ${count}\n`;
            }
            content += '\n';
            // Group by component
            const componentEndpoints = {};
            for (const endpoint of api.endpoints) {
                if (!componentEndpoints[endpoint.component]) {
                    componentEndpoints[endpoint.component] = [];
                }
                componentEndpoints[endpoint.component].push(endpoint);
            }
            content += `**Endpoints by Component:**\n`;
            for (const [component, endpoints] of Object.entries(componentEndpoints)) {
                content += `- ${this.capitalize(component)}: ${endpoints.length} endpoints\n`;
            }
            content += '\n';
        }
        return content;
    }
    generateDataFlow(context) {
        const { extendedWorkflow } = context;
        let content = `## Data Flow\n\n`;
        // Event-driven flows
        if (extendedWorkflow?.events && Object.keys(extendedWorkflow.events).length > 0) {
            content += `### Event-Driven Architecture\n\n`;
            content += `The application uses an event-driven architecture with the following events:\n\n`;
            // Add event flow diagram
            content += this.generateEventFlowDiagram(extendedWorkflow);
            // Add detailed event documentation
            for (const [eventName, event] of Object.entries(extendedWorkflow.events)) {
                const evt = event;
                content += `#### ${eventName}\n\n`;
                if (evt.description) {
                    content += `${evt.description}\n\n`;
                }
                if (evt.payload) {
                    content += `**Payload:**\n`;
                    content += '```json\n';
                    content += `{\n`;
                    for (const [key, type] of Object.entries(evt.payload)) {
                        content += `  "${key}": "${type}",\n`;
                    }
                    content += `}\n`;
                    content += '```\n\n';
                }
            }
        }
        // Workflow flows
        if (extendedWorkflow?.workflows && Object.keys(extendedWorkflow.workflows).length > 0) {
            content += `### Workflows\n\n`;
            for (const [workflowName, workflowDef] of Object.entries(extendedWorkflow.workflows)) {
                const wf = workflowDef;
                content += `#### ${this.capitalize(workflowName.replace(/_/g, ' '))}\n\n`;
                if (wf.description) {
                    content += `${wf.description}\n\n`;
                }
                if (wf.actor) {
                    content += `**Actor:** ${wf.actor}\n\n`;
                }
                if (wf.steps && wf.steps.length > 0) {
                    content += `**Steps:**\n\n`;
                    for (let i = 0; i < wf.steps.length; i++) {
                        const step = wf.steps[i];
                        content += `${i + 1}. **${step.action}** (${step.component})`;
                        if (step.emits) {
                            content += ` → emits \`${step.emits}\``;
                        }
                        if (step.consumes) {
                            content += ` ← consumes \`${step.consumes}\``;
                        }
                        content += '\n';
                    }
                    content += '\n';
                }
            }
        }
        return content;
    }
    generateDeploymentArchitecture(context) {
        const { extendedWorkflow } = context;
        let content = `## Deployment Architecture\n\n`;
        content += `### Containerization\n\n`;
        content += `The application is containerized using Docker for consistent deployment across environments.\n\n`;
        // Stages
        if (extendedWorkflow?.stages) {
            content += `### Environments\n\n`;
            for (const [stageName, stage] of Object.entries(extendedWorkflow.stages)) {
                const stg = stage;
                content += `#### ${this.capitalize(stageName)}\n\n`;
                if (stg.domain) {
                    content += `- **Domain:** ${stg.domain}\n`;
                }
                if (stg.infrastructure?.databases) {
                    content += `- **Database:** Configured\n`;
                }
                if (stg.config) {
                    const cfg = stg.config;
                    if (cfg.log_level) {
                        content += `- **Log Level:** ${cfg.log_level}\n`;
                    }
                }
                content += '\n';
            }
        }
        else {
            content += `The application supports multiple deployment environments (local, staging, production).\n\n`;
        }
        return content;
    }
    generateSecurityArchitecture(context) {
        const { extendedWorkflow } = context;
        const auth = extendedWorkflow?.auth;
        if (!auth || !auth.enabled) {
            return '';
        }
        let content = `## Security Architecture\n\n`;
        content += `### Authentication & Authorization\n\n`;
        content += `**Provider:** ${this.capitalize(auth.provider || 'Custom')}\n\n`;
        if (auth.strategies && auth.strategies.length > 0) {
            content += `**Strategies:** ${auth.strategies.join(', ')}\n\n`;
        }
        // Check if API has role-based access
        if (extendedWorkflow?.api?.endpoints) {
            const hasRoles = extendedWorkflow.api.endpoints.some((e) => e.roles && e.roles.length > 0);
            if (hasRoles) {
                content += `**Authorization:** Role-based access control (RBAC)\n\n`;
            }
        }
        content += `### API Security\n\n`;
        content += `- Authentication required for protected endpoints\n`;
        content += `- Bearer token authentication\n`;
        content += `- CORS configuration for frontend access\n\n`;
        return content;
    }
    /**
     * Generate event flow diagram using Mermaid
     */
    generateEventFlowDiagram(workflow) {
        const events = workflow.events || {};
        const hasRedis = workflow.technology?.cache?.provider?.includes('redis');
        if (!hasRedis) {
            return '';
        }
        let content = `### Event Flow Diagram\n\n`;
        content += 'The following diagram shows how events flow through the system:\n\n';
        content += '```mermaid\n';
        content += 'sequenceDiagram\n';
        content += '    participant API as API Endpoint\n';
        content += '    participant Bus as Event Bus (Redis)\n';
        content += '    participant Handler as Event Handler\n';
        content += '    participant WS as WebSocket Server\n';
        content += '    participant Client as Frontend Client\n\n';
        // Generate flow for each event type
        const eventNames = Object.keys(events);
        for (let i = 0; i < eventNames.length && i < 3; i++) {
            const eventName = eventNames[i];
            content += `    Note over API,Client: ${eventName}\n`;
            content += `    API->>Bus: emit ${eventName}\n`;
            content += `    Bus->>Handler: subscribe ${eventName}\n`;
            content += `    Bus->>WS: forward ${eventName}\n`;
            content += `    WS->>Client: broadcast ${eventName}\n`;
            if (i < eventNames.length - 1 && i < 2) {
                content += '\n';
            }
        }
        if (eventNames.length > 3) {
            content += `\n    Note over API,Client: ... and ${eventNames.length - 3} more events\n`;
        }
        content += '```\n\n';
        // Add explanation
        content += '**Event Flow Steps:**\n\n';
        content += '1. **API Endpoint** emits events after successful operations (create, update, delete)\n';
        content += '2. **Event Bus** (Redis Pub/Sub) distributes events to all subscribers\n';
        content += '3. **Event Handlers** process events for business logic (notifications, analytics, etc.)\n';
        content += '4. **WebSocket Server** receives events and broadcasts to connected clients\n';
        content += '5. **Frontend Clients** receive real-time updates via WebSocket subscriptions\n\n';
        return content;
    }
}
exports.ArchitectureTemplate = ArchitectureTemplate;
//# sourceMappingURL=architecture-template.js.map