"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphBuilder = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
class GraphBuilder {
    constructor() {
        this.nodes = new Map();
        this.links = new Map();
        this.changeFrequency = new Map();
    }
    buildGraph(files, dependencyMap) {
        this.nodes.clear();
        this.links.clear();
        // Create nodes for all files
        for (const filePath of files) {
            this.addNode(filePath);
        }
        // Create links based on dependencies
        for (const [source, targets] of Object.entries(dependencyMap)) {
            for (const target of targets) {
                this.addLink(source, target, 'import');
            }
        }
        return this.getGraphData();
    }
    addNode(filePath) {
        if (this.nodes.has(filePath)) {
            return this.nodes.get(filePath);
        }
        let stats = null;
        try {
            stats = fs.statSync(filePath);
        }
        catch (error) {
            // File might have been deleted
        }
        const node = {
            id: filePath,
            name: path.basename(filePath),
            path: filePath,
            type: this.getFileType(filePath),
            size: stats ? stats.size : 0,
            lastModified: stats ? stats.mtimeMs : Date.now(),
            connections: 0,
            changeFrequency: this.changeFrequency.get(filePath) || 0
        };
        this.nodes.set(filePath, node);
        return node;
    }
    updateNode(filePath, changes) {
        const node = this.nodes.get(filePath);
        if (!node) {
            return null;
        }
        Object.assign(node, changes);
        // Update last modified
        try {
            const stats = fs.statSync(filePath);
            node.lastModified = stats.mtimeMs;
            node.size = stats.size;
        }
        catch (error) {
            // File might have been deleted
        }
        // Increment change frequency
        const freq = this.changeFrequency.get(filePath) || 0;
        this.changeFrequency.set(filePath, freq + 1);
        node.changeFrequency = freq + 1;
        return node;
    }
    removeNode(filePath) {
        // Remove all links connected to this node
        const linksToRemove = [];
        for (const [linkId, link] of this.links.entries()) {
            if (link.source === filePath || link.target === filePath) {
                linksToRemove.push(linkId);
            }
        }
        linksToRemove.forEach(linkId => this.links.delete(linkId));
        return this.nodes.delete(filePath);
    }
    addLink(source, target, type) {
        const linkId = `${source}->${target}`;
        if (this.links.has(linkId)) {
            return this.links.get(linkId);
        }
        // Only add link if both nodes exist
        if (!this.nodes.has(source) || !this.nodes.has(target)) {
            // Ensure both nodes exist
            if (!this.nodes.has(source))
                this.addNode(source);
            if (!this.nodes.has(target))
                this.addNode(target);
        }
        const link = {
            source,
            target,
            type
        };
        this.links.set(linkId, link);
        // Update connection counts
        const sourceNode = this.nodes.get(source);
        const targetNode = this.nodes.get(target);
        if (sourceNode)
            sourceNode.connections = (sourceNode.connections || 0) + 1;
        if (targetNode)
            targetNode.connections = (targetNode.connections || 0) + 1;
        return link;
    }
    removeLink(source, target) {
        const linkId = `${source}->${target}`;
        const removed = this.links.delete(linkId);
        if (removed) {
            // Update connection counts
            const sourceNode = this.nodes.get(source);
            const targetNode = this.nodes.get(target);
            if (sourceNode && sourceNode.connections)
                sourceNode.connections--;
            if (targetNode && targetNode.connections)
                targetNode.connections--;
        }
        return removed;
    }
    getGraphData() {
        return {
            nodes: Array.from(this.nodes.values()),
            links: Array.from(this.links.values())
        };
    }
    getNode(filePath) {
        return this.nodes.get(filePath);
    }
    getFileType(filePath) {
        const ext = path.extname(filePath).toLowerCase();
        const typeMap = {
            '.js': 'javascript',
            '.jsx': 'javascript',
            '.ts': 'typescript',
            '.tsx': 'typescript',
            '.mjs': 'javascript',
            '.cjs': 'javascript',
            '.json': 'json',
            '.css': 'style',
            '.scss': 'style',
            '.sass': 'style',
            '.less': 'style',
            '.html': 'markup',
            '.md': 'markdown',
            '.txt': 'text',
            '.yml': 'config',
            '.yaml': 'config',
            '.toml': 'config',
            '.env': 'config'
        };
        return typeMap[ext] || 'other';
    }
    getStats() {
        return {
            fileCount: this.nodes.size,
            connectionCount: this.links.size,
            changeCount: Array.from(this.changeFrequency.values()).reduce((a, b) => a + b, 0),
            lastChangeTime: Math.max(...Array.from(this.nodes.values()).map(n => n.lastModified))
        };
    }
}
exports.GraphBuilder = GraphBuilder;
//# sourceMappingURL=GraphBuilder.js.map