import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { restoreImageReferences } from "./dump/image-restoration.mjs";
import { ScreenshotItem } from "./screenshot-item.mjs";
export * from "./yaml.mjs";
function _define_property(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
class UIContext {
}
class ServiceError extends Error {
    constructor(message, dump){
        super(message), _define_property(this, "dump", void 0);
        this.name = 'ServiceError';
        this.dump = dump;
    }
}
function replacerForDumpSerialization(_key, value) {
    if (value && value.constructor?.name === 'Page') return '[Page object]';
    if (value && value.constructor?.name === 'Browser') return '[Browser object]';
    if (value && 'function' == typeof value.toSerializable) return value.toSerializable();
    return value;
}
function reviverForDumpDeserialization(key, value) {
    if ('screenshot' !== key || 'object' != typeof value || null === value) return value;
    if (ScreenshotItem.isSerialized(value)) return value;
    'base64' in value && value.base64;
    return value;
}
class ExecutionDump {
    serialize(indents) {
        return JSON.stringify(this.toJSON(), replacerForDumpSerialization, indents);
    }
    toJSON() {
        return {
            logTime: this.logTime,
            name: this.name,
            description: this.description,
            tasks: this.tasks.map((task)=>({
                    ...task,
                    recorder: task.recorder || []
                })),
            aiActContext: this.aiActContext
        };
    }
    static fromSerializedString(serialized) {
        const parsed = JSON.parse(serialized, reviverForDumpDeserialization);
        return new ExecutionDump(parsed);
    }
    static fromJSON(data) {
        return new ExecutionDump(data);
    }
    collectScreenshots() {
        const screenshots = [];
        for (const task of this.tasks){
            if (task.uiContext?.screenshot instanceof ScreenshotItem) screenshots.push(task.uiContext.screenshot);
            if (task.recorder) {
                for (const record of task.recorder)if (record.screenshot instanceof ScreenshotItem) screenshots.push(record.screenshot);
            }
        }
        return screenshots;
    }
    constructor(data){
        _define_property(this, "logTime", void 0);
        _define_property(this, "name", void 0);
        _define_property(this, "description", void 0);
        _define_property(this, "tasks", void 0);
        _define_property(this, "aiActContext", void 0);
        this.logTime = data.logTime;
        this.name = data.name;
        this.description = data.description;
        this.tasks = data.tasks;
        this.aiActContext = data.aiActContext;
    }
}
class GroupedActionDump {
    serialize(indents) {
        return JSON.stringify(this.toJSON(), replacerForDumpSerialization, indents);
    }
    serializeWithInlineScreenshots(indents) {
        const processValue = (obj)=>{
            if (obj instanceof ScreenshotItem) return {
                base64: obj.base64
            };
            if (Array.isArray(obj)) return obj.map(processValue);
            if (obj && 'object' == typeof obj) {
                const entries = Object.entries(obj).map(([key, value])=>[
                        key,
                        processValue(value)
                    ]);
                return Object.fromEntries(entries);
            }
            return obj;
        };
        const data = processValue(this.toJSON());
        return JSON.stringify(data, null, indents);
    }
    toJSON() {
        return {
            sdkVersion: this.sdkVersion,
            groupName: this.groupName,
            groupDescription: this.groupDescription,
            modelBriefs: this.modelBriefs,
            executions: this.executions.map((exec)=>exec.toJSON()),
            deviceType: this.deviceType
        };
    }
    static fromSerializedString(serialized) {
        const parsed = JSON.parse(serialized, reviverForDumpDeserialization);
        return new GroupedActionDump(parsed);
    }
    static fromJSON(data) {
        return new GroupedActionDump(data);
    }
    collectAllScreenshots() {
        const screenshots = [];
        for (const execution of this.executions)screenshots.push(...execution.collectScreenshots());
        return screenshots;
    }
    serializeToFiles(basePath) {
        const screenshotsDir = `${basePath}.screenshots`;
        if (!existsSync(screenshotsDir)) mkdirSync(screenshotsDir, {
            recursive: true
        });
        const screenshotMap = {};
        const screenshots = this.collectAllScreenshots();
        for (const screenshot of screenshots)if (screenshot.hasBase64()) {
            const imagePath = join(screenshotsDir, `${screenshot.id}.${screenshot.extension}`);
            const rawBase64 = screenshot.rawBase64;
            writeFileSync(imagePath, Buffer.from(rawBase64, 'base64'));
            screenshotMap[screenshot.id] = imagePath;
        }
        writeFileSync(`${basePath}.screenshots.json`, JSON.stringify(screenshotMap), 'utf-8');
        writeFileSync(basePath, this.serialize(), 'utf-8');
    }
    static fromFilesAsInlineJson(basePath) {
        const dumpString = readFileSync(basePath, 'utf-8');
        const screenshotsMapPath = `${basePath}.screenshots.json`;
        if (!existsSync(screenshotsMapPath)) return dumpString;
        const screenshotMap = JSON.parse(readFileSync(screenshotsMapPath, 'utf-8'));
        const imageMap = {};
        for (const [id, filePath] of Object.entries(screenshotMap))if (existsSync(filePath)) {
            const data = readFileSync(filePath);
            const mime = filePath.endsWith('.jpeg') || filePath.endsWith('.jpg') ? 'jpeg' : 'png';
            imageMap[id] = `data:image/${mime};base64,${data.toString('base64')}`;
        }
        const dumpData = JSON.parse(dumpString);
        const processedData = restoreImageReferences(dumpData, imageMap);
        return JSON.stringify(processedData);
    }
    static cleanupFiles(basePath) {
        const filesToClean = [
            basePath,
            `${basePath}.screenshots.json`,
            `${basePath}.screenshots`
        ];
        for (const filePath of filesToClean)try {
            rmSync(filePath, {
                force: true,
                recursive: true
            });
        } catch  {}
    }
    static getFilePaths(basePath) {
        return [
            basePath,
            `${basePath}.screenshots.json`,
            `${basePath}.screenshots`
        ];
    }
    constructor(data){
        _define_property(this, "sdkVersion", void 0);
        _define_property(this, "groupName", void 0);
        _define_property(this, "groupDescription", void 0);
        _define_property(this, "modelBriefs", void 0);
        _define_property(this, "executions", void 0);
        _define_property(this, "deviceType", void 0);
        this.sdkVersion = data.sdkVersion;
        this.groupName = data.groupName;
        this.groupDescription = data.groupDescription;
        this.modelBriefs = data.modelBriefs;
        this.executions = data.executions.map((exec)=>exec instanceof ExecutionDump ? exec : ExecutionDump.fromJSON(exec));
        this.deviceType = data.deviceType;
    }
}
export { ExecutionDump, GroupedActionDump, ServiceError, UIContext };

//# sourceMappingURL=types.mjs.map