import fs from "node:fs";
import path from "node:path";
import { createHash } from "node:crypto";
import { OmniFlowSessionExportSchema } from "dp-shared";
/**
 * Center session sync.
 *
 * dp-center stores the OmniFlow extension JSON export. dp-worker only pulls
 * that artifact into the local workspace when the center content hash changes;
 * Chrome startup then copies it into the bundled OmniFlow extension, and the
 * extension imports proxy/timezone/cookies before browser launch is considered
 * complete.
 */
const SESSION_META_FILENAME = ".session-meta.json";
const OMNI_FLOW_SESSION_FILENAME = "omni-flow-session.json";
export function sessionMetaPath(workspace) {
    return path.join(workspace, SESSION_META_FILENAME);
}
export function omniFlowSessionPath(workspace) {
    return path.join(workspace, ".dipclaw", OMNI_FLOW_SESSION_FILENAME);
}
export async function readLocalSessionMeta(workspace) {
    const p = sessionMetaPath(workspace);
    if (!fs.existsSync(p))
        return null;
    try {
        const raw = fs.readFileSync(p, "utf-8");
        const parsed = JSON.parse(raw);
        if (typeof parsed.content_hash !== "string" ||
            typeof parsed.last_local_modified_at !== "string" ||
            typeof parsed.synced_at !== "string") {
            return null;
        }
        return parsed;
    }
    catch {
        return null;
    }
}
export async function writeLocalSessionMeta(workspace, meta) {
    const p = sessionMetaPath(workspace);
    fs.writeFileSync(p, JSON.stringify(meta, null, 2) + "\n", "utf-8");
}
export async function syncOmniFlowSessionBlob(workspace, blob, depsOverride) {
    const dest = omniFlowSessionPath(workspace);
    const local = await readLocalSessionMeta(workspace);
    if (local?.content_hash === blob.content_hash && fs.existsSync(dest)) {
        const localHash = createHash("sha256")
            .update(fs.readFileSync(dest))
            .digest("hex");
        if (localHash === blob.content_hash) {
            return {
                status: "skipped",
                reason: "hash-match",
                content_hash: blob.content_hash,
                path: dest,
            };
        }
    }
    const fetchUrlToBuffer = depsOverride?.fetchUrlToBuffer ?? defaultFetchUrlToBuffer;
    const buf = await fetchUrlToBuffer(blob.r2_get_url);
    if (buf.byteLength !== blob.size_bytes) {
        throw new Error(`OmniFlow session size mismatch: expected ${blob.size_bytes}, got ${buf.byteLength}`);
    }
    const actualHash = createHash("sha256").update(Buffer.from(buf)).digest("hex");
    if (actualHash !== blob.content_hash) {
        throw new Error(`OmniFlow session hash mismatch: expected ${blob.content_hash}, got ${actualHash}`);
    }
    const raw = Buffer.from(buf).toString("utf8");
    let json;
    try {
        json = JSON.parse(raw);
    }
    catch {
        throw new Error("OmniFlow session is not valid JSON");
    }
    const parsed = OmniFlowSessionExportSchema.safeParse(json);
    if (!parsed.success) {
        throw new Error(`Invalid OmniFlow session: ${parsed.error.issues
            .map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`)
            .join("; ")}`);
    }
    fs.mkdirSync(path.dirname(dest), { recursive: true });
    fs.writeFileSync(dest, Buffer.from(buf));
    const now = (depsOverride?.now ?? Date.now)();
    const isoNow = new Date(now).toISOString();
    await writeLocalSessionMeta(workspace, {
        content_hash: blob.content_hash,
        synced_at: isoNow,
        last_local_modified_at: isoNow,
    });
    return {
        status: "applied",
        content_hash: blob.content_hash,
        path: dest,
    };
}
async function defaultFetchUrlToBuffer(url) {
    const res = await fetch(url);
    if (!res.ok) {
        throw new Error(`Session blob fetch failed: ${res.status} ${res.statusText}`);
    }
    return new Uint8Array(await res.arrayBuffer());
}
//# sourceMappingURL=session-sync.js.map