import { extractErrorMsg, getTimestamp, getTimestampInTicks } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
import { getGib, getGibInfo } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
import { GLOBAL_LOG_A_LOT } from "../../core-constants.mjs";
import { RAW_EXPORT_ATOM } from "./import-export-constants.mjs";
import { compressIbGibGraphToString, serializeGraphToString } from "../other/other-helper.web.mjs";
import { getTjpAddr } from "../other/ibgib-helper.mjs";
const logalot = GLOBAL_LOG_A_LOT;
/**
 * builds the ib for a {@link RawExportIbGib_V1}
 */
export function getRawExportIb({ data, }) {
    const lc = `[${getRawExportIb.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 158dfaeb9613a1531be71a9735184624)`);
        }
        const { graphSize, dependencyGraphAsString, timestamp } = data;
        const graphStringLength = dependencyGraphAsString.length;
        const timestampInTicks = getTimestampInTicks(timestamp);
        const compressDescription = data.compression === 'gzip' ? 'gzip' : 'raw';
        if (!data.timestamp) {
            throw new Error(`(UNEXPECTED) data.timestamp falsy? (E: 2f5bc88488cbf260634239a8a8396825)`);
        }
        const date = new Date(data.timestamp);
        const { ib, gib } = getIbAndGib({ ibGibAddr: data.contextIbGibAddr });
        const gibInfo = getGibInfo({ gib });
        const tjpGib = gibInfo.tjpGib ?? gib;
        /**
         * make it easiest to sort in a file explorer but still be readable.
         *
         * timestampInTicks is not easily human-readable
         */
        const dateString = date.toISOString().slice(0, 19)
            .replace('T', '_').replace(/:/g, '').replace(/ /g, '_');
        // it's just too much to include the entire ib as well I think
        // let safeSubtextOfThisIb = getSaferSubstring({
        //     text: ib.replace(' ', '___'),
        //     length: 20, // wth
        // });
        return `${RAW_EXPORT_ATOM} ${dateString} ${compressDescription} ${graphSize} ${graphStringLength} ${tjpGib}`;
        // let exportIb = `ibgib_export ${nowString} ${compress ? 'gzip' : 'raw'} ${safeSubtextOfThisIb} ${gib}`;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * space-delimited info contained in ib.
 *
 * atow (06/2025)
 *   `${RAW_EXPORT_ATOM} ${dateString} ${compressDescription} ${graphSize} ${graphStringLength} ${tjpGib}`;
 * OLD (02/2024)
 *   `${RAW_EXPORT_ATOM} ${timestampInTicks} ${graphSize} ${graphStringLength}`
 */
export function parseRawExportIb({ ib, }) {
    const lc = `[${parseRawExportIb.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 3297e51184f87a45d343d8654b165324)`);
        }
        const [atom, dateString, compressDescription, graphSizeStr, graphStringLengthStr, tjpGib] = ib.split(' ');
        if (atom !== RAW_EXPORT_ATOM) {
            throw new Error(`atom (${atom}) !== ${RAW_EXPORT_ATOM} (E: ad7545da5b8c4baeb15d86e92d657524)`);
        }
        const graphSize = Number.parseInt(graphSizeStr);
        if (Number.isNaN(graphSize) || graphSize < 0) {
            throw new Error(`graphSize (${graphSizeStr}) is not a positive integer. (E: 2b43d9d3462f6e16547b121bccef9b24)`);
        }
        const graphStringLength = Number.parseInt(graphStringLengthStr);
        if (Number.isNaN(graphStringLength) || graphStringLength < 0) {
            throw new Error(`graphStringLength (${graphStringLengthStr}) is not a positive integer. (E: 112ceccee1a54b19ab4f4662b6694ba0)`);
        }
        const compression = compressDescription === 'gzip' ? 'gzip' : undefined;
        return { atom, dateString, graphSize, graphStringLength, compression, tjpGib, };
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
export async function getRawExportIbGib({ ibGib, metaspace, space, compress, live, ignoreErrors,
// detach,
// detachRel8nNames,
 }) {
    const lc = `[${getRawExportIbGib.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 0b6ba8608ba8bde0682a0936b9a01825)`);
        }
        if (!ibGib) {
            throw new Error(`(UNEXPECTED) ibGib falsy? (E: d2898eea744360865f0da5fb91baae22)`);
        }
        const ibGibAddr = getIbGibAddr({ ibGib });
        // if (preparingExport) {
        //   console.warn(`${lc} already preparing export. (W: cb31b23a313247f0ad128dd984645db4)`);
        //   return; /* <<<< returns early */
        // }
        const errorInfos = [];
        // preparingExport = true;
        // build an ibgib that contains the entire dependency graph of this.ibGib and save it
        const validationErrors = await validateIbGibIntrinsically({ ibGib }) ?? [];
        if (validationErrors.length > 0) {
            const errorMsg = `ibGib had validation errors: ${validationErrors} (E: 84890bbc0598192498178a98ae299825)`;
            if (ignoreErrors) {
                errorInfos.push({ errorMsg, ibGibAddr });
            }
            else {
                throw new Error(errorMsg);
            }
        }
        // build the data
        const resGraph = await metaspace.getDependencyGraph({
            ibGib,
            live,
            space,
        });
        const dependencyGraphAsString = compress ?
            await compressIbGibGraphToString({ graph: resGraph }) :
            await serializeGraphToString({ graph: resGraph });
        const tjpAddr = getTjpAddr({ ibGib, defaultIfNone: 'incomingAddr' }) ?? ibGibAddr;
        const now = new Date();
        let exportData = {
            contextIbGibAddr: ibGibAddr,
            tjpAddr,
            dependencyGraphAsString,
            graphSize: Object.keys(resGraph).length,
            timestamp: getTimestamp(now),
            timestampMs: now.getMilliseconds(),
        };
        if (compress) {
            exportData.compression = 'gzip';
        }
        // [no rel8ns because this is a self-contained export ibgib]
        // gib
        const exportIbGib = {
            ib: getRawExportIb({ data: exportData }),
            data: exportData,
        };
        let exportGib = await getGib({ ibGib: exportIbGib, hasTjp: false });
        exportIbGib.gib = exportGib;
        if (logalot || true) {
            console.log(`${lc} JSON.stringify(exportIbGib).length: ${JSON.stringify(exportIbGib).length} (I: db3a8d913a91d8fc5d6e45981e034822)`);
        }
        return {
            rawExportIbGib: exportIbGib,
            manifest: Object.keys(resGraph),
            errors: errorInfos.length > 0 ? errorInfos : undefined,
        };
        // // at this point, we have a possibly quite large ibGib whose data includes
        // // every single ibgib that this.ibGib relates to (its dependency graph).
        // // so now we can save this file and later import from it.
        // // thank you SO, OP and volzotan at https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser
        // // set the anchor's href to a data stream
        // var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportIbGib));
        // // get the filename for the anchor to suggest for the "download"
        // let exportAddr = getIbGibAddr({ ibGib: exportIbGib });
        // const filename = `${exportAddr}.json`;
        // // if (this.web) {
        //     // trigger the click
        //     const dlAnchorElemId ='export-ibgib-anchor';
        //     const dlAnchorElem = document.getElementById(dlAnchorElemId);
        //     if (!dlAnchorElem) { throw new Error(`(UNEXPECTED) dlAnchorElem falsy? should be an element with id ${dlAnchorElemId}? (E: 51dfe2d823eedeefb8b9c9580090e625)`); }
        //     dlAnchorElem.setAttribute("href", dataStr);
        //     dlAnchorElem.setAttribute("download", filename);
        //     dlAnchorElem.click();
        // } else {
        //     // let res = await Filesystem.requestPermissions();
        //     await Filesystem.writeFile({
        //         data: dataStr,
        //         directory: Directory.ExternalStorage,
        //         path: `/Download/${filename}`,
        //         encoding: Encoding.UTF8,
        //         recursive: true,
        //     });
        // }
        // await Dialog.alert({ title: 'export succeeded', message: 'way to go, the export succeeded' });
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
//# sourceMappingURL=import-export-helper.web.mjs.map