import { extractErrorMsg, getUUID, pretty } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
import { getGib } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
import { GIB } from "@ibgib/ts-gib/dist/V1/constants.mjs";
import { spaceNameIsValid } from "../../../../witness/space/space-helper.mjs";
import { DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS, } from "../../../../witness/space/space-constants.mjs";
import { InnerSpace_V1, } from "../../inner-space/inner-space-v1.mjs";
const innerSpaces = {};
/**
 * Extracts the spaceId from the ib string.
 *
 * ib format: `witness space [classname] [name] [id] [type] [subtype]`
 */
export function getSpaceIdFromIb(ib) {
    if (!ib) {
        throw new Error(`ib required. (E: 7c28c8e1a8a24345bb344155b4131422)`);
    }
    const parts = ib.split(' ');
    // witness space classname name id ...
    // 0       1     2         3    4
    if (parts.length < 5) {
        throw new Error(`invalid space ib format: ${ib} (E: 14a84497e59648949822067786481223)`);
    }
    return parts[4];
}
/**
 * Manually registers a space in the module-level registry.
 * Use this when creating spaces outside of the standard factory functions
 * (e.g. via direct constructor calls) to ensure they are resolvable by DTO.
 */
export const registerInnerSpace = (space) => {
    const spaceId = getSpaceIdFromIb(space.ib);
    innerSpaces[spaceId] = space;
};
/**
 * Resets the internal registry of spaces.
 * USE FOR TESTING ONLY.
 */
export const resetInnerSpaces = () => {
    Object.keys(innerSpaces).forEach(key => delete innerSpaces[key]);
};
export const fnCreateNewLocalSpace = async ({ allowCancel, spaceName, getFnPrompt, logalot, }) => {
    const lc = `[${fnCreateNewLocalSpace.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: a9bc8c7d54cb4bafae4c4aa515d71580)`);
        }
        if (spaceName && !spaceNameIsValid(spaceName)) {
            throw new Error(`spaceName (${spaceName}) is invalid.  (E: 7769ee9ed9874ff28548214efc3639c2)`);
            // throw because this is used in RLI and automated testing...
        }
        if (!spaceName) {
            const promptName = async () => {
                const fnPrompt = getFnPrompt();
                const resName = await fnPrompt({
                    title: 'greetings program', msg: `all of your data is stored locally on your device's "local space".

so name your space with alphanumerics & underscores, like 'phone_alice' or 'web_bob_foo', or leave blank and get a random name.

Enter space name:
`
                });
                if (resName === '' && !allowCancel) {
                    spaceName = 'space_' + (await getUUID()).slice(0, 10);
                }
                else {
                    if (resName && spaceNameIsValid(resName)) {
                        spaceName = resName;
                    }
                }
            };
            // ...prompt for name
            await promptName();
        }
        // ...create in memory with defaults
        const data = {
            version: '1',
            name: spaceName || ('in-memory-space_' + (await getUUID()).slice(0, 10)),
            uuid: await getUUID(),
            description: 'ephemeral in-memory space',
            persistOptsAndResultIbGibs: false,
            validateIbGibAddrsMatchIbGibs: true,
            trace: false,
            allowPrimitiveArgs: false,
            catchAllErrors: true,
            longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,
        };
        const newLocalSpace = new InnerSpace_V1(/*initialData*/ data, /*initialRel8ns*/ undefined);
        if (logalot) {
            console.log(`${lc} localSpace.ib: ${newLocalSpace.ib}`);
        }
        if (logalot) {
            console.log(`${lc} localSpace.gib: ${newLocalSpace.gib} (before sha256v1)`);
        }
        if (logalot) {
            console.log(`${lc} localSpace.data: ${pretty(newLocalSpace.data || 'falsy')}`);
        }
        if (logalot) {
            console.log(`${lc} localSpace.rel8ns: ${pretty(newLocalSpace.rel8ns || 'falsy')}`);
        }
        newLocalSpace.gib = await getGib({ ibGib: newLocalSpace, hasTjp: false });
        if (newLocalSpace.gib === GIB) {
            throw new Error(`localSpace.gib not updated correctly.`);
        }
        if (logalot) {
            console.log(`${lc} localSpace.gib: ${newLocalSpace.gib} (after sha256v1)`);
        }
        registerInnerSpace(newLocalSpace);
        return newLocalSpace;
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
};
export const fnDtoToSpace = async (spaceDto) => {
    const lc = `[fnDtoToSpace]`;
    try {
        // afaict we should be dealing with the space itself in memory, so just
        // return the reference itself.
        if (spaceDto.ibGibs) {
            return spaceDto;
        }
        else {
            // test is outputting a lot of these logs
            // console.log(`${lc} spaceDto: ${pretty(spaceDto)} (I: d69ab87f2fa8360ff8e60e78aa15c825)`); // I want to keep this in if we need to turn the logging back on
            if (!spaceDto.data) {
                throw new Error(`invalid spaceDto. InnerSpace_V1 should have truthy data. (E: d402fda7a6a53668b655c2885029a423)`);
            }
            // console.dir(spaceDto); // I want to keep this in if we need to turn the logging back on
            const spaceId = getSpaceIdFromIb(spaceDto.ib);
            // console.log(`${lc} spaceDto.gib: ${spaceDto.gib}\ninnerSpaces keys:\n${Object.keys(innerSpaces).join('\n')}`);
            const existingSpace = innerSpaces[spaceId];
            if (existingSpace) {
                return existingSpace;
            }
            else {
                // it's not the reference and nothing registered so far, so make a new one? (but warn)
                console.warn(`${lc} in memory innerspace dto that isnt' the reference to the object itself in memory, and we don't have it in the inner spaces map? i guess we'll create a new one from the dto (W: b8973f3a43f546eeaf59f60331896e75)`);
                let space = new InnerSpace_V1(spaceDto.data, spaceDto.rel8ns);
                await space.initialized;
                registerInnerSpace(space);
                return space;
            }
        }
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
};
//# sourceMappingURL=metaspace-innerspace-helper.mjs.map