/**
 * @module outer-space
 * Outer spaces are spaces connecting local inner spaces.
 * ATOW there is just sync spaces, but definitely just the beginning.
 *
 * ## on future implementations, CRDT-like behavior
 *
 * I just realized that when merging, I can actually create a meta transform
 * ibgib to maintain the order of transforms.
 */
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
import { VALID_SPACE_SUBTYPES, VALID_SPACE_TYPES, } from '../space-types.mjs';
import { StatusCode, } from './outer-space-types.mjs';
import { OUTER_SPACE_DEFAULT_IB_DELIMITER } from './outer-space-constants.mjs';
import { getSpecialRel8dIbGibs } from '../space-helper.mjs';
import { SpecialIbGibType } from '../../../common/other/other-types.mjs';
import { SYNC_SPACE_REL8N_NAME } from '../space-constants.mjs';
/**
 * for verbose logging
 */
const logalot = GLOBAL_LOG_A_LOT;
/**
 * Composes ib with given params info.
 *
 * @returns ib string with given info encoded
 */
export function getStatusIb({ sagaId, statusCode, spaceType, spaceSubtype, delimiter, }) {
    const lc = `[${getStatusIb.name}]`;
    try {
        if (!sagaId) {
            throw new Error(`sagaId required. (E: cfc923bb29ee4aa788e947b6416740e6)`);
        }
        if (statusCode === null || statusCode === undefined) {
            throw new Error(`status code required. (E: 4e0d232a9955496695012623c2e17ca2)`);
        }
        if (!Object.values(StatusCode).includes(statusCode)) {
            throw new Error(`invalid status code (${statusCode}) (E: 91d7655424c44d9680fff099ee2b54d2)`);
        }
        if (!spaceType) {
            throw new Error(`spaceType required. (E: 86e98694a56a4f599e98e50abf0eed43)`);
        }
        if (!spaceSubtype) {
            throw new Error(`spaceSubtype required. (E: 4857d4677ee34e95aeb2251dd633909e)`);
        }
        delimiter = delimiter || OUTER_SPACE_DEFAULT_IB_DELIMITER;
        return `status ${sagaId} ${statusCode} ${spaceType} ${spaceSubtype}`;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
/**
 * Parses the given `statusIb` and returns the info object.
 *
 * @returns info from parsing the status ib
 */
export function getStatusIbInfo({ statusIb, delimiter, }) {
    const lc = `[${getStatusIb.name}]`;
    try {
        if (!statusIb) {
            throw new Error(`statusIb required. (E: 09e23e8622cf456cadb0c3d0aadc3be9)`);
        }
        delimiter = delimiter || OUTER_SPACE_DEFAULT_IB_DELIMITER;
        // atow `status ${sagaId} ${statusCode} ${spaceType} ${spaceSubtype}`;
        const pieces = statusIb.split(delimiter);
        const sagaId = pieces[1];
        if (sagaId === null || sagaId === undefined) {
            throw new Error(`sagaId is null/undefined. (E: 5de2861a6afb48e1a1c89d0402a4ea63)`);
        }
        const statusCode = pieces[2]; // tenatively cast as StatusCode
        if (!Object.values(StatusCode).includes(statusCode)) {
            throw new Error(`invalid/unknown status code (${statusCode}) (E: 7580860df7b344b3992148552e80a85e)`);
        }
        const spaceType = pieces[3];
        if (spaceType === null || spaceType === undefined) {
            throw new Error(`spaceType is null/undefined. (E: 12473d35e77b451bb59bb05c03cb8b64)`);
        }
        if (!VALID_SPACE_TYPES.includes(spaceType)) {
            throw new Error(`invalid/unknown spaceType (${spaceType}) (E: d3ba9add427f49dda34f265f3225d9db)`);
        }
        const spaceSubtype = pieces[4];
        if (spaceSubtype === null || spaceSubtype === undefined) {
            throw new Error(`spaceSubtype is null/undefined. (E: 6da7ae919d0b4a22b4ee685520b6c946)`);
        }
        if (!VALID_SPACE_SUBTYPES.includes(spaceSubtype)) {
            throw new Error(`invalid/unknown spaceSubtype (${spaceSubtype}) (E: 703ed1aee44447a294b3e1cf0984baba)`);
        }
        return { statusCode, spaceType, spaceSubtype, sagaId, delimiter };
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
export async function getSyncSpaces({ space, }) {
    const lc = `[${getSyncSpaces.name}]`;
    try {
        if (!space) {
            throw new Error(`space required. (E: c03f80eca6b045b9a73b0aafa44cdf26)`);
        }
        let syncSpaces = await getSpecialRel8dIbGibs({
            type: SpecialIbGibType.outerspaces,
            rel8nName: SYNC_SPACE_REL8N_NAME,
            space,
        });
        return syncSpaces;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
/**
 * gets the sync space ibgibs referenced in the given local {@link localSpace}
 * and loads them into their corresponding witness classes.
 *
 * note: atow (03/2024) this throws if a factory function isn't found for ANY of
 * the sync spaces found. later on, when multiple kinds of sync spaces are in
 * existence, this behavior should change because it would be quite possible
 * that we have multiple spaces that may not have a loaded factory function
 * available.
 *
 * @see {@link SpaceFactoryFnMap}
 *
 * @returns sync space witnesses
 */
export async function getSyncSpaces_witnesses({ localSpace, spaceFactoryFns, }) {
    const lc = `[${getSyncSpaces_witnesses.name}]`;
    try {
        if (!localSpace) {
            throw new Error(`localSpace required. (E: c03f80eca6b045b9a73b0aafa44cdf26)`);
        }
        let resSpaceWitnesses = [];
        const syncSpaceDtos = await getSyncSpaces({ space: localSpace });
        for (let i = 0; i < syncSpaceDtos.length; i++) {
            const syncSpaceDto = syncSpaceDtos[i];
            if (!syncSpaceDto.data) {
                throw new Error(`(UNEXPECTED) syncSpaceDto.data falsy? (E: 5404f124b8bb781c0a52b3cc9f8e6524)`);
            }
            const { type, subtype } = syncSpaceDto.data;
            if (!type) {
                throw new Error(`(UNEXPECTED) syncSpaceDto.data.type falsy? (E: b3461e0df562d301fc84d68d95f91424)`);
            }
            if (!subtype) {
                throw new Error(`(UNEXPECTED) syncSpaceDto.data.subtype falsy? (E: 524c471119564b4b817261f9e1edcafb)`);
            }
            const fnFactory_typeSubset = spaceFactoryFns[syncSpaceDto.data.type] ?? {};
            const fnFactory = fnFactory_typeSubset[syncSpaceDto.data.subtype];
            if (!fnFactory) {
                throw new Error(`(UNEXPECTED) no factory function found for type (${type}) and subtype (${subtype})? (E: fd726f9049ade511f679d1de621dec24)`);
            }
            const spaceWitness = await fnFactory(syncSpaceDto);
            resSpaceWitnesses.push(spaceWitness);
        }
        if (syncSpaceDtos.length !== resSpaceWitnesses.length) {
            throw new Error(`(UNEXPECTED) syncSpaceDtos.length !== resSpaceWitnesses.length? (E: c85b1c93fce972a57683da727e6dc224)`);
        }
        return resSpaceWitnesses;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
export function getSrcLocalSpaceId({ participants, }) {
    const lc = `[${getSrcLocalSpaceId.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 43c9a4f1fa1bbc944b98f8eed2f81924)`);
        }
        const participants_src = participants.filter(x => x.s_d === 'src');
        if (participants_src.length !== 1) {
            throw new Error(`(UNEXPECTED) participants_src.length !== 1? atow (03/2024) only one src participant is expected. (E: ed4b3ae15f5da34c77655553aaf82224)`);
        }
        return participants_src.at(0).id;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
//# sourceMappingURL=outer-space-helper.mjs.map