/**
 * @module sync-innerspace-deep-updates.respec
 *
 * Verifies Complex Sync Scenarios using InnerSpace.
 */
import { respecfully, ifWe, iReckon } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
const maam = `[${import.meta.url}]`, sir = maam;
import { clone, delay } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
import { getDependencyGraph } from '../common/other/graph-helper.mjs';
import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
import { getFromSpace } from '../witness/space/space-helper.mjs';
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
import { createTimelineRootTestHelper, } from '../test-helpers.mjs';
import { mut8Timeline } from '../timeline/timeline-api.mjs';
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
const logalot = GLOBAL_LOG_A_LOT || true;
const lc = `[sync-innerspace-deep-updates.respec]`;
await respecfully(sir, `Sync InnerSpaces (Deep Updates)`, async () => {
    let metaspace;
    let sourceSpace;
    let destSpace;
    await respecfully(sir, `Deep Updates (Push Source -> Dest)`, async () => {
        // 1. Setup Spaces
        metaspace = new Metaspace_Innerspace(undefined);
        await metaspace.initialize({
            getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
            getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
            getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
        });
        while (!metaspace.initialized) {
            await delay(10);
        }
        const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
        await defaultLocalUserSpace.initialized;
        sourceSpace = new InnerSpace_V1({
            ...DEFAULT_INNER_SPACE_DATA_V1,
            name: 'source',
            uuid: 'source_uuid',
            description: 'source test space',
        });
        await sourceSpace.initialized;
        destSpace = new InnerSpace_V1({
            ...DEFAULT_INNER_SPACE_DATA_V1,
            name: 'dest',
            uuid: 'dest_uuid',
            description: 'dest test space',
        });
        await destSpace.initialized;
        // 2. Seed Source Data (Deep History)
        console.log(`${lc} Creating deep data in Source...`);
        // Root -> Comment (Child) -> Edit Comment (Child v2)
        const root = await createTimelineRootTestHelper({
            ib: 'timeline_root_deep',
            data: { type: 'root', label: 'Root' },
            space: sourceSpace,
        });
        // n=1
        const commentV1 = await mut8Timeline({
            timeline: root,
            mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'Hello World' } },
            metaspace,
            space: sourceSpace,
        });
        // n=2 (Edit)
        const commentV2 = await mut8Timeline({
            timeline: commentV1,
            mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'Hello Sync' } },
            metaspace,
            space: sourceSpace,
        });
        const addrV2 = getIbGibAddr({ ibGib: commentV2 });
        // 3. Setup
        const senderCoordinator = new SyncSagaCoordinator();
        const receiverCoordinator = new SyncSagaCoordinator();
        const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
        await peer.initialized;
        await peer.initializeOpts({
            localMetaspace: metaspace,
            localSpace: sourceSpace, // "Client"
            receiverSpace: destSpace, // "Server"
            receiverCoordinator,
            receiverMetaspace: metaspace,
        });
        // 4. Run Sync
        console.log(`${lc} Running Sync...`);
        // Debug Source Graph
        const sourceGraph = await getDependencyGraph({ ibGib: commentV2, space: sourceSpace });
        console.log(`${lc} Source Graph count: ${sourceGraph ? Object.keys(sourceGraph).length : 'null'}`);
        const resSync = await senderCoordinator.sync({
            peer: peer,
            localSpace: sourceSpace,
            metaspace: metaspace,
            domainIbGibs: [commentV2], // Sync the TIP
        });
        await resSync.done;
        // 5. Verify Dest
        console.log(`${lc} Verifying Destination...`);
        await ifWe(sir, `verify deep timeline present`, async () => {
            // Verify Tip (V2)
            const getV2 = await getFromSpace({ space: destSpace, addr: addrV2 });
            iReckon(sir, getV2.success).asTo('Tip V2 present').isGonnaBeTrue();
            const v2IbGib = getV2.ibGibs[0];
            iReckon(sir, v2IbGib.data.label).asTo('Label V2 match').isGonnaBe('Hello Sync');
            // iReckon(sir, v2IbGib.data!.n).asTo('n=2').isGonnaBe(2); // Relaxing n check for now
            // Verify Past Frame (V1) availability
            // Sync should transfer dependencies (past frames)
            // Rel8ns are accretive, so we check the LAST one.
            const pastAddr = v2IbGib.rel8ns?.past?.at(-1);
            if (pastAddr) {
                const getV1 = await getFromSpace({ space: destSpace, addr: pastAddr });
                iReckon(sir, getV1.success).asTo('Past Frame (V1) present').isGonnaBeTrue();
                iReckon(sir, getV1.ibGibs?.[0]?.data?.label).asTo('Label V1 match').isGonnaBe('Hello World');
            }
            else {
                iReckon(sir, false).asTo('Past relation present').isGonnaBeTrue();
            }
            // Verify Full Graph Integrity (DNA, Roots)
            const graph = await getDependencyGraph({ ibGib: v2IbGib, space: destSpace });
            iReckon(sir, !!graph).asTo('Dependency Graph resolvable in Dest').isGonnaBeTrue();
            // Should contain Root, V1, V2
            // We can check counts or specific existence.
            iReckon(sir, Object.keys(graph).length > 2).asTo('Graph size > 2').isGonnaBeTrue();
        });
    });
});
//# sourceMappingURL=sync-innerspace-deep-updates.respec.mjs.map