import { mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
const SNAPSHOT_DIR = 'debug/dom-snapshots';
const DATA_URL_PATTERN = /^data:image\/png;base64,([A-Za-z0-9+/=]+)$/;
export class ControlPlaneLayoutSnapshotsController {
    static async save(stateRoot, snapshot) {
        if (!ControlPlaneLayoutSnapshotsController.isRecord(snapshot)) {
            throw new Error('Layout snapshot payload must be an object.');
        }
        const outputDir = join(stateRoot, SNAPSHOT_DIR);
        await mkdir(outputDir, { recursive: true });
        const capturedAt = typeof snapshot.capturedAt === 'string' ? snapshot.capturedAt : new Date().toISOString();
        const timestamp = ControlPlaneLayoutSnapshotsController.sanitizeFilenamePart(capturedAt.replaceAll(':', '-'));
        const label = ControlPlaneLayoutSnapshotsController.deriveSnapshotLabel(snapshot);
        const basename = `${timestamp}-${label}`;
        const jsonPath = join(outputDir, `${basename}.json`);
        const persistedSnapshot = ControlPlaneLayoutSnapshotsController.cloneJsonRecord(snapshot);
        const screenshotPath = await ControlPlaneLayoutSnapshotsController.persistScreenshot(outputDir, basename, persistedSnapshot);
        await writeFile(jsonPath, `${JSON.stringify(persistedSnapshot, null, 2)}\n`, 'utf8');
        return screenshotPath ? { jsonPath, screenshotPath } : { jsonPath };
    }
    static async persistScreenshot(outputDir, basename, snapshot) {
        const screenshot = snapshot.screenshot;
        if (!ControlPlaneLayoutSnapshotsController.isRecord(screenshot) || screenshot.status !== 'captured' || typeof screenshot.dataUrl !== 'string') {
            return undefined;
        }
        const match = DATA_URL_PATTERN.exec(screenshot.dataUrl);
        if (!match?.[1]) {
            snapshot.screenshot = {
                ...screenshot,
                status: 'failed',
                reason: 'Screenshot data URL was not a PNG image.',
                dataUrl: undefined,
            };
            return undefined;
        }
        const screenshotPath = join(outputDir, `${basename}.png`);
        await writeFile(screenshotPath, Buffer.from(match[1], 'base64'));
        snapshot.screenshot = {
            ...screenshot,
            path: screenshotPath,
            dataUrl: undefined,
        };
        return screenshotPath;
    }
    static deriveSnapshotLabel(snapshot) {
        const appState = ControlPlaneLayoutSnapshotsController.isRecord(snapshot.appState) ? snapshot.appState : {};
        const parts = [
            typeof appState.activeTab === 'string' ? appState.activeTab : 'control-plane',
            typeof appState.selectedSessionId === 'string' ? appState.selectedSessionId : undefined,
            ControlPlaneLayoutSnapshotsController.isRecord(appState.pendingApproval) && typeof appState.pendingApproval.tool === 'string' ? `approval-${appState.pendingApproval.tool}` : undefined,
        ].filter((part) => Boolean(part));
        return ControlPlaneLayoutSnapshotsController.sanitizeFilenamePart(parts.join('-')) || 'snapshot';
    }
    static sanitizeFilenamePart(value) {
        return value
            .toLowerCase()
            .replace(/[^a-z0-9._-]+/g, '-')
            .replace(/-+/g, '-')
            .replace(/^-|-$/g, '')
            .slice(0, 120);
    }
    static cloneJsonRecord(value) {
        return JSON.parse(JSON.stringify(value));
    }
    static isRecord(value) {
        return typeof value === 'object' && value !== null && !Array.isArray(value);
    }
}
//# sourceMappingURL=layout-snapshots.js.map