/**
 * Project Structure Detector
 *
 * Automatically detects project management structure from:
 * - Existing increments and work items
 * - Source system metadata (Jira, ADO, GitHub)
 * - Environment variables
 *
 * Supports various hierarchies:
 * - Jira: Epic → Story → Sub-task
 * - ADO: Epic → Feature → User Story → Task
 * - GitHub: Milestone → Issue (or flat Issues)
 * - Custom: Detected from patterns
 */
import * as fs from 'fs';
import * as path from 'path';
import * as yaml from 'js-yaml';
export class ProjectStructureDetector {
    constructor(projectRoot = process.cwd()) {
        this.projectRoot = projectRoot;
    }
    /**
     * Detect project structure from existing increments
     */
    async detectStructure() {
        const incrementsDir = path.join(this.projectRoot, '.specweave', 'increments');
        if (!fs.existsSync(incrementsDir)) {
            return this.getDefaultStructure().structure;
        }
        const increments = fs.readdirSync(incrementsDir)
            .filter(name => /^\d{4}/.test(name))
            .slice(0, 5);
        if (increments.length === 0) {
            return this.getDefaultStructure().structure;
        }
        const analysis = await this.analyzeIncrements(increments);
        return analysis.structure;
    }
    /**
     * Analyze increments to detect structure
     */
    async analyzeIncrements(increments) {
        const evidence = [];
        let hasEpics = false;
        let hasFeatures = false;
        let hasMilestones = false;
        let hasInitiatives = false;
        let source = 'manual';
        const workItemTypesSeen = new Set();
        for (const increment of increments) {
            const specPath = path.join(this.projectRoot, '.specweave', 'increments', increment, 'spec.md');
            if (!fs.existsSync(specPath))
                continue;
            const content = fs.readFileSync(specPath, 'utf-8');
            const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
            if (!frontmatterMatch)
                continue;
            const frontmatter = yaml.load(frontmatterMatch[1]);
            // Detect source
            if (frontmatter.jira) {
                source = 'jira';
                evidence.push(`Found Jira metadata in ${increment}`);
                if (frontmatter.jira.epic_key) {
                    hasEpics = true;
                    evidence.push(`Found Epic link: ${frontmatter.jira.epic_key}`);
                }
            }
            if (frontmatter.ado) {
                source = 'ado';
                evidence.push(`Found ADO metadata in ${increment}`);
                if (frontmatter.ado.feature_id) {
                    hasFeatures = true;
                    evidence.push(`Found Feature link: ${frontmatter.ado.feature_id}`);
                }
                if (frontmatter.ado.epic_id) {
                    hasEpics = true;
                    evidence.push(`Found Epic link in ADO`);
                }
            }
            if (frontmatter.github) {
                source = 'github';
                evidence.push(`Found GitHub metadata in ${increment}`);
                if (frontmatter.github.milestone) {
                    hasMilestones = true;
                    evidence.push(`Found Milestone: ${frontmatter.github.milestone}`);
                }
            }
            // Analyze work items
            if (frontmatter.work_items && Array.isArray(frontmatter.work_items)) {
                frontmatter.work_items.forEach((item) => {
                    if (item.type) {
                        workItemTypesSeen.add(item.type);
                    }
                });
            }
        }
        // Determine hierarchy level
        let hierarchyLevel;
        if (hasInitiatives && hasEpics && hasFeatures) {
            hierarchyLevel = 'three_level';
            evidence.push('Detected 3-level hierarchy (Initiative → Epic → Feature → Stories)');
        }
        else if (hasEpics || hasFeatures || hasMilestones) {
            hierarchyLevel = 'two_level';
            evidence.push(`Detected 2-level hierarchy with ${hasEpics ? 'Epics' : hasFeatures ? 'Features' : 'Milestones'}`);
        }
        else if (workItemTypesSeen.size > 0) {
            hierarchyLevel = 'single_parent';
            evidence.push('Detected single-level grouping by type');
        }
        else {
            hierarchyLevel = 'flat';
            evidence.push('Detected flat structure (no hierarchy)');
        }
        // Determine work item types
        const workItemTypes = this.inferWorkItemTypes(source, hierarchyLevel, workItemTypesSeen);
        // Determine grouping strategy
        const groupingStrategy = this.inferGroupingStrategy(source, hierarchyLevel, workItemTypesSeen);
        return {
            structure: {
                source,
                hierarchyLevel,
                workItemTypes,
                groupingStrategy
            },
            confidence: Math.min(increments.length / 5, 1), // More samples = higher confidence
            evidence,
            sampleIncrements: increments
        };
    }
    /**
     * Infer work item types from source and hierarchy
     */
    inferWorkItemTypes(source, hierarchyLevel, typesSeen) {
        switch (source) {
            case 'jira':
                if (hierarchyLevel === 'three_level') {
                    return { topLevel: 'Initiative', parentLevel: 'Epic', itemLevel: 'Story', subItemLevel: 'Sub-task' };
                }
                return { parentLevel: 'Epic', itemLevel: 'Story', subItemLevel: 'Sub-task' };
            case 'ado':
                if (hierarchyLevel === 'three_level') {
                    return { topLevel: 'Epic', parentLevel: 'Feature', itemLevel: 'User Story', subItemLevel: 'Task' };
                }
                if (hierarchyLevel === 'two_level') {
                    return { parentLevel: 'Feature', itemLevel: 'User Story', subItemLevel: 'Task' };
                }
                return { itemLevel: 'User Story', subItemLevel: 'Task' };
            case 'github':
                if (hierarchyLevel === 'two_level') {
                    return { parentLevel: 'Milestone', itemLevel: 'Issue' };
                }
                return { itemLevel: 'Issue' };
            default:
                if (typesSeen.has('story')) {
                    return { parentLevel: 'Epic', itemLevel: 'Story', subItemLevel: 'Task' };
                }
                if (typesSeen.has('issue')) {
                    return { itemLevel: 'Issue' };
                }
                return { itemLevel: 'Item' };
        }
    }
    /**
     * Infer grouping strategy from source and hierarchy
     */
    inferGroupingStrategy(source, hierarchyLevel, typesSeen) {
        // If we see story/bug/task types, group by type
        if (typesSeen.has('story') || typesSeen.has('bug') || typesSeen.has('task')) {
            return 'by_type';
        }
        // If we have parent level (epic, feature, milestone), group by parent
        if (hierarchyLevel === 'two_level' || hierarchyLevel === 'three_level') {
            return 'by_parent';
        }
        // GitHub typically uses flat or by_label
        if (source === 'github') {
            return 'by_label';
        }
        // Default to by_type
        return 'by_type';
    }
    /**
     * Get default structure when no increments exist
     */
    getDefaultStructure() {
        // Try to infer from environment or use sensible defaults
        const envSource = (process.env.JIRA_DOMAIN ? 'jira' :
            process.env.AZURE_DEVOPS_ORG ? 'ado' :
                process.env.GITHUB_REPOSITORY ? 'github' : 'manual');
        const defaultStructures = {
            jira: {
                source: 'jira',
                hierarchyLevel: 'two_level',
                workItemTypes: {
                    parentLevel: 'Epic',
                    itemLevel: 'Story',
                    subItemLevel: 'Sub-task'
                },
                groupingStrategy: 'by_type'
            },
            ado: {
                source: 'ado',
                hierarchyLevel: 'two_level',
                workItemTypes: {
                    parentLevel: 'Feature',
                    itemLevel: 'User Story',
                    subItemLevel: 'Task'
                },
                groupingStrategy: 'by_type'
            },
            github: {
                source: 'github',
                hierarchyLevel: 'two_level',
                workItemTypes: {
                    parentLevel: 'Milestone',
                    itemLevel: 'Issue'
                },
                groupingStrategy: 'by_label'
            },
            manual: {
                source: 'manual',
                hierarchyLevel: 'two_level',
                workItemTypes: {
                    parentLevel: 'Feature',
                    itemLevel: 'Story',
                    subItemLevel: 'Task'
                },
                groupingStrategy: 'by_type'
            }
        };
        return {
            structure: defaultStructures[envSource],
            confidence: 0.5,
            evidence: ['Using default structure based on environment'],
            sampleIncrements: []
        };
    }
    /**
     * Get structure summary for display
     */
    getStructureSummary(structure) {
        const hierarchy = this.getHierarchyDescription(structure);
        const grouping = this.getGroupingDescription(structure.groupingStrategy);
        return `Source: ${structure.source.toUpperCase()}\nHierarchy: ${hierarchy}\nGrouping: ${grouping}`;
    }
    getHierarchyDescription(structure) {
        const types = structure.workItemTypes;
        const parts = [];
        if (types.topLevel)
            parts.push(types.topLevel);
        if (types.parentLevel)
            parts.push(types.parentLevel);
        parts.push(types.itemLevel);
        if (types.subItemLevel)
            parts.push(types.subItemLevel);
        return parts.join(' → ');
    }
    getGroupingDescription(strategy) {
        const descriptions = {
            by_type: 'Group by Type (Story, Bug, Task)',
            by_parent: 'Group by Parent (Epic, Feature, Milestone)',
            by_priority: 'Group by Priority (P1, P2, P3)',
            by_label: 'Group by Label/Tag',
            flat: 'Flat List (No Grouping)',
            custom: 'Custom Grouping'
        };
        return descriptions[strategy];
    }
}
//# sourceMappingURL=project-structure-detector.js.map