import * as fs from 'fs';
import * as path from 'path';
export class RepoTreeGenerator {
    repoRoot;
    maxDepth;
    ignorePatterns;
    constructor(repoRoot, options = {}) {
        this.repoRoot = repoRoot;
        this.maxDepth = options.maxDepth ?? 5;
        this.ignorePatterns = new Set(options.ignorePatterns ?? ['.git', 'node_modules', 'dist', 'coverage', '.next', '.vscode']);
    }
    generate() {
        return this.walk(this.repoRoot, 0);
    }
    walk(dirPath, depth) {
        const stats = fs.statSync(dirPath);
        const name = path.basename(dirPath) || path.basename(this.repoRoot);
        if (depth > this.maxDepth || this.ignorePatterns.has(name) || !stats.isDirectory()) {
            return {
                name,
                type: stats.isDirectory() ? 'directory' : 'file',
                size: stats.isDirectory() ? undefined : stats.size,
            };
        }
        try {
            const entries = fs.readdirSync(dirPath);
            const children = [];
            for (const entry of entries) {
                if (this.ignorePatterns.has(entry))
                    continue;
                const entryPath = path.join(dirPath, entry);
                try {
                    children.push(this.walk(entryPath, depth + 1));
                }
                catch {
                    // ignore unreadable files
                }
            }
            // Sort directories first, then alphabetically
            children.sort((a, b) => {
                if (a.type !== b.type) {
                    return a.type === 'directory' ? -1 : 1;
                }
                return a.name.localeCompare(b.name);
            });
            return {
                name,
                type: 'directory',
                children,
            };
        }
        catch {
            return { name, type: 'directory' };
        }
    }
}
