"use strict";
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024-2026 Gracker (Chris)
// This file is part of SmartPerfetto. See LICENSE for details.
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionTree = void 0;
exports.createSessionTree = createSessionTree;
// =============================================================================
// Session Tree
// =============================================================================
/**
 * 会话树
 */
class SessionTree {
    constructor() {
        this.nodes = new Map();
        this.rootSessionId = null;
    }
    // ===========================================================================
    // Node Management
    // ===========================================================================
    /**
     * 创建根节点
     */
    createRoot(sessionId, branchName = 'main') {
        const node = {
            sessionId,
            parentSessionId: null,
            childSessionIds: [],
            branchName,
            forkCheckpointId: null,
            depth: 0,
            createdAt: Date.now(),
            status: 'active',
        };
        this.nodes.set(sessionId, node);
        this.rootSessionId = sessionId;
        return node;
    }
    /**
     * 添加分叉节点
     */
    addFork(parentSessionId, childSessionId, checkpointId, branchName, hypothesis) {
        const parent = this.nodes.get(parentSessionId);
        if (!parent) {
            throw new Error(`Parent session not found: ${parentSessionId}`);
        }
        const childNode = {
            sessionId: childSessionId,
            parentSessionId,
            childSessionIds: [],
            branchName,
            forkCheckpointId: checkpointId,
            depth: parent.depth + 1,
            createdAt: Date.now(),
            status: 'active',
            hypothesis,
        };
        // 更新父节点
        parent.childSessionIds.push(childSessionId);
        this.nodes.set(parentSessionId, parent);
        // 添加子节点
        this.nodes.set(childSessionId, childNode);
        return childNode;
    }
    /**
     * 获取节点
     */
    getNode(sessionId) {
        return this.nodes.get(sessionId);
    }
    /**
     * 更新节点状态
     */
    updateStatus(sessionId, status) {
        const node = this.nodes.get(sessionId);
        if (node) {
            node.status = status;
            this.nodes.set(sessionId, node);
        }
    }
    /**
     * 更新节点摘要
     */
    updateSummary(sessionId, summary) {
        const node = this.nodes.get(sessionId);
        if (node) {
            node.summary = summary;
            this.nodes.set(sessionId, node);
        }
    }
    /**
     * 删除节点（及其所有子节点）
     */
    removeNode(sessionId, recursive = true) {
        const node = this.nodes.get(sessionId);
        if (!node) {
            return [];
        }
        const removed = [];
        // 递归删除子节点
        if (recursive) {
            for (const childId of node.childSessionIds) {
                removed.push(...this.removeNode(childId, true));
            }
        }
        // 从父节点移除引用
        if (node.parentSessionId) {
            const parent = this.nodes.get(node.parentSessionId);
            if (parent) {
                parent.childSessionIds = parent.childSessionIds.filter(id => id !== sessionId);
                this.nodes.set(node.parentSessionId, parent);
            }
        }
        // 删除当前节点
        this.nodes.delete(sessionId);
        removed.push(sessionId);
        return removed;
    }
    // ===========================================================================
    // Tree Queries
    // ===========================================================================
    /**
     * 获取根节点
     */
    getRoot() {
        return this.rootSessionId ? this.nodes.get(this.rootSessionId) : undefined;
    }
    /**
     * 获取父节点
     */
    getParent(sessionId) {
        const node = this.nodes.get(sessionId);
        if (node?.parentSessionId) {
            return this.nodes.get(node.parentSessionId);
        }
        return undefined;
    }
    /**
     * 获取子节点
     */
    getChildren(sessionId) {
        const node = this.nodes.get(sessionId);
        if (!node) {
            return [];
        }
        return node.childSessionIds
            .map(id => this.nodes.get(id))
            .filter((n) => n !== undefined);
    }
    /**
     * 获取所有祖先节点（从父到根）
     */
    getAncestors(sessionId) {
        const ancestors = [];
        let current = this.nodes.get(sessionId);
        while (current?.parentSessionId) {
            const parent = this.nodes.get(current.parentSessionId);
            if (parent) {
                ancestors.push(parent);
                current = parent;
            }
            else {
                break;
            }
        }
        return ancestors;
    }
    /**
     * 获取所有后代节点（深度优先）
     */
    getDescendants(sessionId) {
        const node = this.nodes.get(sessionId);
        if (!node) {
            return [];
        }
        const descendants = [];
        const stack = [...node.childSessionIds];
        while (stack.length > 0) {
            const currentId = stack.pop();
            const current = this.nodes.get(currentId);
            if (current) {
                descendants.push(current);
                stack.push(...current.childSessionIds);
            }
        }
        return descendants;
    }
    /**
     * 获取兄弟节点
     */
    getSiblings(sessionId) {
        const node = this.nodes.get(sessionId);
        if (!node?.parentSessionId) {
            return [];
        }
        const parent = this.nodes.get(node.parentSessionId);
        if (!parent) {
            return [];
        }
        return parent.childSessionIds
            .filter(id => id !== sessionId)
            .map(id => this.nodes.get(id))
            .filter((n) => n !== undefined);
    }
    /**
     * 获取所有叶子节点
     */
    getLeaves() {
        return Array.from(this.nodes.values()).filter(node => node.childSessionIds.length === 0);
    }
    /**
     * 获取指定状态的节点
     */
    getNodesByStatus(status) {
        return Array.from(this.nodes.values()).filter(node => node.status === status);
    }
    /**
     * 获取指定深度的节点
     */
    getNodesByDepth(depth) {
        return Array.from(this.nodes.values()).filter(node => node.depth === depth);
    }
    // ===========================================================================
    // Tree Analysis
    // ===========================================================================
    /**
     * 获取树的最大深度
     */
    getMaxDepth() {
        let maxDepth = 0;
        for (const node of this.nodes.values()) {
            if (node.depth > maxDepth) {
                maxDepth = node.depth;
            }
        }
        return maxDepth;
    }
    /**
     * 获取活跃分叉数量
     */
    getActiveForkCount() {
        return Array.from(this.nodes.values()).filter(node => node.status === 'active' && node.parentSessionId !== null).length;
    }
    /**
     * 获取节点总数
     */
    getNodeCount() {
        return this.nodes.size;
    }
    /**
     * 检查是否为根节点
     */
    isRoot(sessionId) {
        return sessionId === this.rootSessionId;
    }
    /**
     * 检查是否为叶子节点
     */
    isLeaf(sessionId) {
        const node = this.nodes.get(sessionId);
        return node ? node.childSessionIds.length === 0 : false;
    }
    /**
     * 检查两个节点是否有共同祖先
     */
    haveCommonAncestor(sessionId1, sessionId2) {
        const ancestors1 = new Set(this.getAncestors(sessionId1).map(n => n.sessionId));
        ancestors1.add(sessionId1);
        const ancestors2 = this.getAncestors(sessionId2).map(n => n.sessionId);
        ancestors2.push(sessionId2);
        return ancestors2.some(id => ancestors1.has(id));
    }
    /**
     * 找到两个节点的最近共同祖先
     */
    findLowestCommonAncestor(sessionId1, sessionId2) {
        const ancestors1 = new Set(this.getAncestors(sessionId1).map(n => n.sessionId));
        ancestors1.add(sessionId1);
        // 从 session2 向上找，第一个在 ancestors1 中的就是 LCA
        let current = this.nodes.get(sessionId2);
        while (current) {
            if (ancestors1.has(current.sessionId)) {
                return current;
            }
            if (current.parentSessionId) {
                current = this.nodes.get(current.parentSessionId);
            }
            else {
                break;
            }
        }
        return undefined;
    }
    // ===========================================================================
    // Path Operations
    // ===========================================================================
    /**
     * 获取从根到节点的路径
     */
    getPathFromRoot(sessionId) {
        const path = this.getAncestors(sessionId).reverse();
        const node = this.nodes.get(sessionId);
        if (node) {
            path.push(node);
        }
        return path;
    }
    /**
     * 获取两个节点之间的路径
     */
    getPathBetween(sessionId1, sessionId2) {
        const lca = this.findLowestCommonAncestor(sessionId1, sessionId2);
        if (!lca) {
            return [];
        }
        // 从 session1 到 LCA 的路径
        const path1 = [];
        let current = this.nodes.get(sessionId1);
        while (current && current.sessionId !== lca.sessionId) {
            path1.push(current);
            if (current.parentSessionId) {
                current = this.nodes.get(current.parentSessionId);
            }
            else {
                break;
            }
        }
        // 从 LCA 到 session2 的路径
        const path2 = [];
        current = this.nodes.get(sessionId2);
        while (current && current.sessionId !== lca.sessionId) {
            path2.unshift(current);
            if (current.parentSessionId) {
                current = this.nodes.get(current.parentSessionId);
            }
            else {
                break;
            }
        }
        // 合并路径
        return [...path1, lca, ...path2];
    }
    // ===========================================================================
    // Serialization
    // ===========================================================================
    /**
     * 获取分叉状态
     */
    getForkState() {
        return {
            sessionTree: this.nodes,
            rootSessionId: this.rootSessionId || '',
            activeForkCount: this.getActiveForkCount(),
            lastUpdated: Date.now(),
        };
    }
    /**
     * 序列化为 JSON
     */
    serialize() {
        return {
            sessionTree: Array.from(this.nodes.entries()),
            rootSessionId: this.rootSessionId || '',
            activeForkCount: this.getActiveForkCount(),
            lastUpdated: Date.now(),
        };
    }
    /**
     * 从序列化数据恢复
     */
    static deserialize(data) {
        const tree = new SessionTree();
        tree.nodes = new Map(data.sessionTree);
        tree.rootSessionId = data.rootSessionId || null;
        return tree;
    }
    // ===========================================================================
    // Visualization
    // ===========================================================================
    /**
     * 生成树形可视化字符串
     */
    toTreeString() {
        if (!this.rootSessionId) {
            return '(empty tree)';
        }
        const lines = [];
        this.buildTreeString(this.rootSessionId, '', true, lines);
        return lines.join('\n');
    }
    /**
     * 构建树形字符串（递归）
     */
    buildTreeString(sessionId, prefix, isLast, lines) {
        const node = this.nodes.get(sessionId);
        if (!node) {
            return;
        }
        const connector = isLast ? '└── ' : '├── ';
        const statusIcon = this.getStatusIcon(node.status);
        const summary = node.summary
            ? ` [${node.summary.totalFindings} findings]`
            : '';
        lines.push(`${prefix}${connector}${statusIcon} ${node.branchName} (${sessionId.slice(0, 8)}...)${summary}`);
        const childPrefix = prefix + (isLast ? '    ' : '│   ');
        const children = node.childSessionIds;
        for (let i = 0; i < children.length; i++) {
            this.buildTreeString(children[i], childPrefix, i === children.length - 1, lines);
        }
    }
    /**
     * 获取状态图标
     */
    getStatusIcon(status) {
        switch (status) {
            case 'active':
                return '●';
            case 'completed':
                return '✓';
            case 'merged':
                return '⊕';
            case 'abandoned':
                return '✗';
            case 'expired':
                return '○';
            default:
                return '?';
        }
    }
}
exports.SessionTree = SessionTree;
// =============================================================================
// Factory
// =============================================================================
/**
 * 创建会话树
 */
function createSessionTree() {
    return new SessionTree();
}
exports.default = SessionTree;
//# sourceMappingURL=sessionTree.js.map