import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { getMidsceneRunSubDir } from "@midscene/shared/common";
import { ExecutionDump } from "./types.mjs";
function defaultGroupName(platform, sessionId) {
    return `Midscene ${platform} session ${sessionId}`;
}
function normalizeSessionRecord(session) {
    return {
        sessionId: session.sessionId,
        platform: session.platform,
        groupName: session.groupName ?? defaultGroupName(session.platform, session.sessionId),
        groupDescription: session.groupDescription,
        sdkVersion: session.sdkVersion ?? '',
        modelBriefs: session.modelBriefs ?? [],
        deviceType: session.deviceType ?? session.platform,
        createdAt: session.createdAt ?? Date.now(),
        updatedAt: session.updatedAt ?? Date.now(),
        executionCount: session.executionCount ?? 0,
        reportFilePath: session.reportFilePath
    };
}
function orderedRootExecutionFiles(dir) {
    if (!existsSync(dir)) return [];
    return readdirSync(dir).filter((file)=>/^\d+\.json$/.test(file)).sort((left, right)=>Number.parseInt(left, 10) - Number.parseInt(right, 10));
}
const SessionStore = {
    rootDir () {
        return getMidsceneRunSubDir('session');
    },
    sessionDir (sessionId) {
        return join(SessionStore.rootDir(), sessionId);
    },
    agentFilePath (sessionId) {
        return join(SessionStore.sessionDir(sessionId), 'agent.json');
    },
    executionBasePath (sessionId, order) {
        return join(SessionStore.sessionDir(sessionId), `${order}.json`);
    },
    reportDir (sessionId) {
        const dir = join(SessionStore.sessionDir(sessionId), 'report');
        mkdirSync(dir, {
            recursive: true
        });
        return dir;
    },
    load (sessionId) {
        const filePath = SessionStore.agentFilePath(sessionId);
        if (!existsSync(filePath)) throw new Error(`Session not found: ${sessionId}`);
        return normalizeSessionRecord(JSON.parse(readFileSync(filePath, 'utf-8')));
    },
    save (session) {
        mkdirSync(SessionStore.sessionDir(session.sessionId), {
            recursive: true
        });
        const normalized = normalizeSessionRecord(session);
        writeFileSync(SessionStore.agentFilePath(normalized.sessionId), JSON.stringify(normalized, null, 2), 'utf-8');
        return normalized;
    },
    ensureSession (input) {
        const now = Date.now();
        const filePath = SessionStore.agentFilePath(input.sessionId);
        if (existsSync(filePath)) {
            const existing = SessionStore.load(input.sessionId);
            const mergedModelBriefs = new Set(existing.modelBriefs);
            input.modelBriefs?.forEach((brief)=>mergedModelBriefs.add(brief));
            const next = {
                ...existing,
                platform: input.platform ?? existing.platform,
                groupName: input.groupName ?? existing.groupName ?? defaultGroupName(input.platform, input.sessionId),
                groupDescription: input.groupDescription ?? existing.groupDescription,
                sdkVersion: input.sdkVersion ?? existing.sdkVersion,
                modelBriefs: [
                    ...mergedModelBriefs
                ],
                deviceType: input.deviceType ?? existing.deviceType ?? existing.platform,
                updatedAt: now
            };
            return SessionStore.save(next);
        }
        return SessionStore.save({
            sessionId: input.sessionId,
            platform: input.platform,
            groupName: input.groupName ?? defaultGroupName(input.platform, input.sessionId),
            groupDescription: input.groupDescription,
            sdkVersion: input.sdkVersion ?? '',
            modelBriefs: input.modelBriefs ?? [],
            deviceType: input.deviceType ?? input.platform,
            createdAt: now,
            updatedAt: now,
            executionCount: 0
        });
    },
    markReportGenerated (sessionId, reportFilePath) {
        const session = SessionStore.load(sessionId);
        return SessionStore.save({
            ...session,
            reportFilePath,
            updatedAt: Date.now()
        });
    },
    nextOrder (sessionId) {
        const session = SessionStore.load(sessionId);
        const next = session.executionCount + 1;
        SessionStore.save({
            ...session,
            executionCount: next,
            updatedAt: Date.now()
        });
        return next;
    },
    persistExecution (sessionId, order, execution) {
        const basePath = SessionStore.executionBasePath(sessionId, order);
        ExecutionDump.cleanupFiles(basePath);
        execution.serializeToFiles(basePath);
    },
    buildSessionDump (sessionId) {
        const session = SessionStore.load(sessionId);
        const rootExecutionFiles = orderedRootExecutionFiles(SessionStore.sessionDir(sessionId));
        if (!rootExecutionFiles.length) throw new Error(`Session ${sessionId} has no persisted executions`);
        const executions = [];
        for (const fileName of rootExecutionFiles){
            const basePath = join(SessionStore.sessionDir(sessionId), fileName);
            const inlineJson = ExecutionDump.fromFilesAsInlineJson(basePath);
            executions.push(JSON.parse(inlineJson));
        }
        return {
            sdkVersion: session.sdkVersion,
            groupName: session.groupName,
            groupDescription: session.groupDescription,
            modelBriefs: session.modelBriefs,
            executions,
            deviceType: session.deviceType ?? session.platform
        };
    }
};
function createSessionAgentOptions(input) {
    if (!input.sessionId) return {};
    return {
        generateReport: false,
        sessionId: input.sessionId,
        groupName: input.groupName ?? defaultGroupName(input.platform, input.sessionId),
        groupDescription: input.groupDescription
    };
}
export { SessionStore, createSessionAgentOptions };

//# sourceMappingURL=session-store.mjs.map