/**
 * @module sync-conflict-adv-multitimelines.withid.respec
 *
 * Verifies Conflict Resolution strategies in SyncSagaCoordinator under identity.
 * Reproduces divergence scenarios and asserts resolution behavior.
 */
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 { TestTransformer, } from '../test-helpers.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 { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
import { getIbGibsFromCache_fallbackToSpaces, getTjpAddr, } from '../common/other/ibgib-helper.mjs';
import { getDependencyGraph, graphsAreEquivalent } from '../common/other/graph-helper.mjs';
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
import { SyncConflictStrategy } from './sync-constants.mjs';
import { KeystoneService_V1 } from '../keystone/keystone-service-v1.mjs';
import { KEYSTONE_VERB_SYNC, POOL_ID_SYNC, } from '../keystone/keystone-constants.mjs';
import { createStandardPoolConfig } from '../keystone/keystone-config-builder.mjs';
import { KeystoneReplenishStrategy } from '../keystone/keystone-types.mjs';
const logalot = GLOBAL_LOG_A_LOT;
const lc = sir;
const SENDER_SECRET = 'test-sender-secret-conflict-adv-multitimelines-withid';
const SENDER_IDENTITY_SYNC_POOL_CONFIG = createStandardPoolConfig({
    id: POOL_ID_SYNC,
    salt: 'senderidentitysyncsaltconflictadvmultitimelineswithid',
    verbs: [KEYSTONE_VERB_SYNC],
    size: 200,
    sequential: 1,
    random: 1,
    targetBinding: 2,
    replenishStrategy: KeystoneReplenishStrategy.topUp,
});
const TEST_REL8N_NAME = 'testrel8n';
await respecfully(sir, `Multi-round/timeline permutations with Identity`, async () => {
    // #region Init/Setup
    const 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;
    const sourceSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'source',
        uuid: 'source_uuid',
        description: 'source test space',
    });
    await sourceSpace.initialized;
    const destSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'dest',
        uuid: 'dest_uuid',
        description: 'dest test space',
    });
    await destSpace.initialized;
    const testTransformer = new TestTransformer(metaspace, sourceSpace, destSpace);
    if (logalot) {
        console.log(`${lc} Setting up Coordinators...`);
    }
    const senderCoordinator = new SyncSagaCoordinator();
    const receiverCoordinator = new SyncSagaCoordinator();
    // Setup Identities
    const keystoneSvc = new KeystoneService_V1();
    const r1_senderIdentity_v0_source = await keystoneSvc.genesis({
        masterSecret: SENDER_SECRET,
        configs: [SENDER_IDENTITY_SYNC_POOL_CONFIG],
        metaspace,
        space: sourceSpace,
    });
    // Register identity in both spaces
    await metaspace.put({ ibGib: r1_senderIdentity_v0_source, space: destSpace });
    await metaspace.registerNewIbGib({ ibGib: r1_senderIdentity_v0_source, space: destSpace });
    let senderIdentityLatestSource = r1_senderIdentity_v0_source;
    async function newTestPeer() {
        const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
        await peer.initialized;
        await peer.initializeOpts({
            localMetaspace: metaspace,
            localSpace: sourceSpace,
            receiverSpace: destSpace,
            receiverCoordinator: receiverCoordinator,
            receiverMetaspace: metaspace,
        });
        return peer;
    }
    // #endregion Init/Setup
    // #region Round 1: Seed common history
    const _r1 = testTransformer.newRound({
        name: 'r1_seedCommonHistory',
        description: 'Create alpha v0 and v1 on source, sync to dest so both v0 and v1 are established as synced.',
    });
    if (logalot) {
        console.log(`${lc} Creating common History...`);
    }
    const r1_alpha_v0_source = await testTransformer.create({
        atom: 'alpha',
        in: 'source',
        name: 'r1_alpha_v0_source',
    });
    const alpha_tjpAddr = getTjpAddr({ ibGib: r1_alpha_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
    // Create v1 (common) - will be synced to dest
    const r1_alpha_v1_source_common = await testTransformer.mut8({
        stepInfo: r1_alpha_v0_source,
        strField: 'commonField',
        name: 'r1_alpha_v1_source_common'
    });
    await respecfully(sir, `r1 verify pre`, async () => {
        await ifWe(sir, 'dest should NOT have alpha', async () => {
            const resGet = await getFromSpace({
                space: destSpace,
                addr: alpha_tjpAddr,
            });
            iReckon(sir, resGet.success).asTo('getFromSpace should return false for missing timeline').isGonnaBeFalse();
            iReckon(sir, resGet.ibGibs?.length ?? 0).asTo('Dest should NOT have alpha timeline yet').isGonnaBe(0);
        });
    });
    const peerR1 = await newTestPeer();
    const r1_syncSaga = await senderCoordinator.sync({
        peer: peerR1,
        localSpace: sourceSpace,
        metaspace,
        domainIbGibs: [r1_alpha_v1_source_common.ibGib],
        conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        senderIdentity: senderIdentityLatestSource,
        fnSenderSecret: async () => SENDER_SECRET,
    });
    await r1_syncSaga.done;
    if (logalot) {
        console.log(`${lc} r1_syncSaga Complete.`);
    }
    await respecfully(sir, `r1 verify post`, async () => {
        await ifWe(sir, 'dest should have alpha', async () => {
            const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
                addrs: [r1_alpha_v0_source.addr],
                space: destSpace,
            });
            iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
            if (alpha_dest) {
                const depGraph_alpha_source = await getDependencyGraph({ ibGib: r1_alpha_v0_source.ibGib, space: sourceSpace });
                const depGraph_alpha_dest = await getDependencyGraph({ ibGib: alpha_dest, space: destSpace });
                const alphaDepsAreEqual = graphsAreEquivalent({
                    graphA: depGraph_alpha_source, graphB: depGraph_alpha_dest
                });
                iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBe(true);
            }
        });
        await ifWe(sir, 'sessionIdentity evolved for Round 1', async () => {
            const latestS = peerR1.currentSessionIdentity;
            iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
            if (latestS) {
                iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(2);
            }
        });
    });
    // Get alpha_v1_common from destSpace for Round 2
    const resGetDest = await getFromSpace({ space: destSpace, addr: r1_alpha_v1_source_common.addr });
    if (!resGetDest.success || !resGetDest.ibGibs || resGetDest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from destSpace after sync. (E: r1_fail)`);
    }
    const alpha_v1_common_onDest = resGetDest.ibGibs[0];
    // Fetch evolved user identity from space
    const latestSenderIdentityAddrR1 = await metaspace.getLatestAddr({
        addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
        space: sourceSpace,
    });
    if (!latestSenderIdentityAddrR1) {
        throw new Error("Could not find latest sender identity after R1");
    }
    const resGetSenderIR1 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR1 });
    senderIdentityLatestSource = resGetSenderIR1.ibGibs[0];
    // Copy/register evolved user identity to dest space
    await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
    await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
    // #endregion Round 1: Seed common history
    // #region Round 2: Create Divergence (v2source vs v2dest)
    const _r2 = testTransformer.newRound({
        name: 'r2_divergent_edits',
        description: 'Create conflicts on alpha, add beta relation on source, separate edit on dest'
    });
    // #region r2 source edits
    if (logalot) {
        console.log(`${lc} Creating Divergence...`);
    }
    // Source: Create beta, mutate alpha fieldA, add beta relation
    const r2_beta_v0_source = await testTransformer.create({
        atom: 'beta',
        in: 'source',
        data: { fieldA: 'beta field A created on source' },
        name: 'r2_beta_v0_source'
    });
    const r2_alpha_v2_source_arbitraryMut8 = await testTransformer.mut8({
        ibGib: r1_alpha_v1_source_common.ibGib,
        in: 'source',
        strField: 'fieldA',
        name: 'r2_alpha_v2_source_arbitraryMut8',
        comments_snake_plus_CamelCase: 'editedOnSource',
    });
    const r2_alpha_v3_source_rel8dBeta = await testTransformer.rel8({
        stepInfo: r2_alpha_v2_source_arbitraryMut8,
        in: 'source',
        targetIbGibs: [r2_beta_v0_source.ibGib],
        rel8nName: TEST_REL8N_NAME,
        name: 'r2_alpha_v3_source_rel8dBeta'
    });
    // #endregion r2 source edits
    // #region r2 dest edits
    // Dest: Mutate alpha fieldB
    const r2_alpha_v2_dest_mut8FieldB = await testTransformer.mut8({
        ibGib: alpha_v1_common_onDest,
        in: 'dest',
        strField: 'fieldB',
        name: 'r2_alpha_v2_dest_mut8FieldB',
        comments_snake_plus_CamelCase: 'editedOnDest',
    });
    if (logalot) {
        console.log(`${lc} Divergence created.`);
    }
    // #endregion r2 dest edits
    await respecfully(sir, `r2 verify pre`, async () => {
        await ifWe(sir, 'dest has alpha v1 common', async () => {
            const destKV = await receiverCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [alpha_v1_common_onDest]
            });
            const alpha_v1_common_tjpAddr_onDest = getTjpAddr({ ibGib: alpha_v1_common_onDest, defaultIfNone: 'incomingAddr' });
            const destTip = destKV[alpha_v1_common_tjpAddr_onDest];
            iReckon(sir, !!destTip).asTo(`Dest KV has timeline tip`).isGonnaBeTruthy();
        });
    });
    const peerR2 = await newTestPeer();
    const r2_syncSaga = await senderCoordinator.sync({
        peer: peerR2,
        localSpace: sourceSpace,
        metaspace,
        domainIbGibs: [r2_alpha_v3_source_rel8dBeta.ibGib],
        conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        senderIdentity: senderIdentityLatestSource,
        fnSenderSecret: async () => SENDER_SECRET,
    });
    await r2_syncSaga.done;
    await respecfully(sir, `r2 verify post`, async () => {
        const alpha_sourceKV_afterSync = await senderCoordinator.getKnowledgeMap({
            space: sourceSpace,
            metaspace,
            domainIbGibs: [r1_alpha_v0_source.ibGib]
        });
        const alpha_source_tipAddr = alpha_sourceKV_afterSync[alpha_tjpAddr];
        const alpha_destKV_afterSync = await senderCoordinator.getKnowledgeMap({
            space: destSpace,
            metaspace,
            domainIbGibs: [r1_alpha_v0_source.ibGib]
        });
        const alpha_dest_tipAddr = alpha_destKV_afterSync[alpha_tjpAddr];
        await ifWe(sir, 'tip addrs match', async () => {
            iReckon(sir, alpha_source_tipAddr).asTo('source/dest tip addrs').isGonnaBe(alpha_dest_tipAddr);
        });
        const resGet_alpha_source_tipAddr = await getFromSpace({ space: sourceSpace, addr: alpha_source_tipAddr });
        const gotten_alpha_source_tipIbGib = resGet_alpha_source_tipAddr.ibGibs[0];
        await ifWe(sir, 'r2 basics of alpha merge', async () => {
            iReckon(sir, alpha_source_tipAddr).not.isGonnaBe(r2_alpha_v3_source_rel8dBeta.addr);
            iReckon(sir, alpha_source_tipAddr).not.isGonnaBe(r2_alpha_v2_dest_mut8FieldB.addr);
            const r2_source_mut8Info = r2_alpha_v2_source_arbitraryMut8.infos[0];
            const r2_dest_mut8Info = r2_alpha_v2_dest_mut8FieldB.infos[0];
            iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_source_mut8Info.key]).isGonnaBe(r2_source_mut8Info.value);
            iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_dest_mut8Info.key]).isGonnaBe(r2_dest_mut8Info.value);
        });
        await ifWe(sir, 'r2 beta and deps synced', async () => {
            const [beta_dest] = await getIbGibsFromCache_fallbackToSpaces({
                addrs: [r2_beta_v0_source.addr],
                space: destSpace,
            });
            iReckon(sir, beta_dest).asTo('beta exists in dest').isGonnaBeTruthy();
        });
        await ifWe(sir, 'sessionIdentity evolved for Round 2', async () => {
            const latestS = peerR2.currentSessionIdentity;
            iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
            if (latestS) {
                iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
            }
        });
    });
    // Fetch evolved user identity from space
    const latestSenderIdentityAddrR2 = await metaspace.getLatestAddr({
        addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
        space: sourceSpace,
    });
    if (!latestSenderIdentityAddrR2) {
        throw new Error("Could not find latest sender identity after R2");
    }
    const resGetSenderIR2 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR2 });
    senderIdentityLatestSource = resGetSenderIR2.ibGibs[0];
    // Copy/register evolved user identity to dest space
    await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
    await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
    // #endregion Round 2: Create Divergence
    // #region Round 3: Multiple Timeline Conflicts
    const _r3 = testTransformer.newRound({
        name: 'r3_multiple_timeline_conflicts',
        description: 'Both alpha AND beta have divergent edits on source vs dest - tests multiple simultaneous grafts'
    });
    // #region r3 source edits
    const resGet_r3_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    const r3_alpha_v3_graftPoint = resGet_r3_alpha_source.ibGibs[0];
    const beta_tjpAddr = getTjpAddr({ ibGib: r2_beta_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
    const resGet_r3_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
    const r3_beta_v0_graftPoint = resGet_r3_beta_source.ibGibs[0];
    // Mutate alpha fieldC on source
    const r3_alpha_v4_source_mut8fieldC = await testTransformer.mut8({
        ibGib: r3_alpha_v3_graftPoint,
        in: 'source',
        strField: 'fieldC',
        name: 'r3_alpha_v4_source_mut8fieldC',
        comments_snake_plus_CamelCase: 'postGraft',
    });
    // Mutate beta betaFieldA on source
    const r3_beta_v1_source = await testTransformer.mut8({
        ibGib: r3_beta_v0_graftPoint,
        in: 'source',
        strField: 'betaFieldA',
        name: 'r3_beta_v1_source',
    });
    // #endregion r3 source edits
    // #region r3 dest edits
    const resGet_r3_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
    const r3_alpha_v3_graftPoint_fromDest = resGet_r3_alpha_dest.ibGibs[0];
    const resGet_r3_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
    const r3_beta_v0_graftPoint_fromDest = resGet_r3_beta_dest.ibGibs[0];
    // Mutate alpha fieldD on dest
    const r3_alpha_v4_dest_mut8fieldD = await testTransformer.mut8({
        ibGib: r3_alpha_v3_graftPoint_fromDest,
        in: 'dest',
        strField: 'fieldD',
        name: 'r3_alpha_v4_dest_mut8fieldD',
        comments_snake_plus_CamelCase: 'postGraft',
    });
    // Mutate beta betaFieldB on dest
    const r3_beta_v1_dest = await testTransformer.mut8({
        ibGib: r3_beta_v0_graftPoint_fromDest,
        in: 'dest',
        strField: 'betaFieldB',
        name: 'r3_beta_v1_dest',
    });
    // #endregion r3 dest edits
    await respecfully(sir, `r3 verify pre`, async () => {
        await ifWe(sir, 'dest has both alpha and beta tips', async () => {
            const destKV = await receiverCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r3_alpha_v3_graftPoint_fromDest, r3_beta_v0_graftPoint_fromDest]
            });
            iReckon(sir, !!destKV[alpha_tjpAddr]).isGonnaBeTruthy();
            iReckon(sir, !!destKV[beta_tjpAddr]).isGonnaBeTruthy();
        });
    });
    const peerR3 = await newTestPeer();
    const r3_syncSaga = await senderCoordinator.sync({
        peer: peerR3,
        localSpace: sourceSpace,
        metaspace,
        domainIbGibs: [r3_alpha_v4_source_mut8fieldC.ibGib, r3_beta_v1_source.ibGib],
        conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        senderIdentity: senderIdentityLatestSource,
        fnSenderSecret: async () => SENDER_SECRET,
    });
    await r3_syncSaga.done;
    await respecfully(sir, `r3 verify post`, async () => {
        const alpha_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const r3_alpha_source_tipAddr = alpha_sourceKV_afterR3[alpha_tjpAddr];
        const alpha_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const r3_alpha_dest_tipAddr = alpha_destKV_afterR3[alpha_tjpAddr];
        const beta_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
        const r3_beta_source_tipAddr = beta_sourceKV_afterR3[beta_tjpAddr];
        const beta_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
        const r3_beta_dest_tipAddr = beta_destKV_afterR3[beta_tjpAddr];
        await ifWe(sir, 'r3 tip addrs match (both timelines)', async () => {
            iReckon(sir, r3_alpha_source_tipAddr).asTo('alpha tip').isGonnaBe(r3_alpha_dest_tipAddr);
            iReckon(sir, r3_beta_source_tipAddr).asTo('beta tip').isGonnaBe(r3_beta_dest_tipAddr);
        });
        const resGet_r3_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r3_alpha_source_tipAddr });
        const r3_alpha_tipIbGib = resGet_r3_alpha_tip.ibGibs[0];
        const resGet_r3_beta_tip = await getFromSpace({ space: sourceSpace, addr: r3_beta_source_tipAddr });
        const r3_beta_tipIbGib = resGet_r3_beta_tip.ibGibs[0];
        await ifWe(sir, 'r3 alpha merge has all four fields (commonField, fieldA, fieldB, fieldC, fieldD)', async () => {
            const r3_alpha_v4_source_mut8Info = r3_alpha_v4_source_mut8fieldC.infos[0];
            const r3_alpha_v4_dest_mut8Info = r3_alpha_v4_dest_mut8fieldD.infos[0];
            iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_source_mut8Info.key]).isGonnaBe(r3_alpha_v4_source_mut8Info.value);
            iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_dest_mut8Info.key]).isGonnaBe(r3_alpha_v4_dest_mut8Info.value);
        });
        await ifWe(sir, 'r3 beta merge has both fields (betaFieldA, betaFieldB)', async () => {
            const r3_source_beta_mut8Info = r3_beta_v1_source.infos[0];
            const r3_dest_beta_mut8Info = r3_beta_v1_dest.infos[0];
            iReckon(sir, r3_beta_tipIbGib.data[r3_source_beta_mut8Info.key]).isGonnaBe(r3_source_beta_mut8Info.value);
            iReckon(sir, r3_beta_tipIbGib.data[r3_dest_beta_mut8Info.key]).isGonnaBe(r3_dest_beta_mut8Info.value);
        });
        await ifWe(sir, 'sessionIdentity evolved for Round 3', async () => {
            const latestS = peerR3.currentSessionIdentity;
            iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
            if (latestS) {
                iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
            }
        });
    });
    // Fetch evolved user identity from space
    const latestSenderIdentityAddrR3 = await metaspace.getLatestAddr({
        addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
        space: sourceSpace,
    });
    if (!latestSenderIdentityAddrR3) {
        throw new Error("Could not find latest sender identity after R3");
    }
    const resGetSenderIR3 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR3 });
    senderIdentityLatestSource = resGetSenderIR3.ibGibs[0];
    // Copy/register evolved user identity to dest space
    await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
    await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
    // #endregion Round 3: Multiple Timeline Conflicts
    // #region Round 4: Chain Edits After Graft
    const _r4 = testTransformer.newRound({
        name: 'r4_chain_edits_after_graft',
        description: 'Post-graft chain edits: mut8 → create gamma → rel8 gamma → mut8 again, tests continued editing on grafted timelines'
    });
    // #region r4 source edits
    const resGet_r4_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    const r4_alpha_v4_graftPoint = resGet_r4_alpha_source.ibGibs[0];
    // Mutate alpha v5 (fieldE) from R3 graft point
    const r4_alpha_v5_source = await testTransformer.mut8({
        ibGib: r4_alpha_v4_graftPoint,
        in: 'source',
        strField: 'fieldE',
        name: 'r4_alpha_v5_source',
        comments_snake_plus_CamelCase: 'postGraft2',
    });
    // Create new gamma timeline
    const r4_gamma_v0_source = await testTransformer.create({
        atom: 'gamma',
        in: 'source',
        data: { gammaField: 'gamma created on source' },
        name: 'r4_gamma_v0_source'
    });
    // Relate alpha to gamma (creates v6)
    const r4_alpha_v6_source_rel8dGamma = await testTransformer.rel8({
        stepInfo: r4_alpha_v5_source,
        in: 'source',
        targetIbGibs: [r4_gamma_v0_source.ibGib],
        rel8nName: TEST_REL8N_NAME,
        name: 'r4_alpha_v6_source_rel8dGamma'
    });
    // Mutate alpha again v7 (fieldF)
    const r4_alpha_v7_source = await testTransformer.mut8({
        ibGib: r4_alpha_v6_source_rel8dGamma.ibGib,
        in: 'source',
        strField: 'fieldF',
        name: 'r4_alpha_v7_source',
        comments_snake_plus_CamelCase: 'chainEnd',
    });
    // Retrieve beta R3 graft point from source
    const resGet_r4_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
    const r4_beta_v1_graftPoint = resGet_r4_beta_source.ibGibs[0];
    // Mutate beta v2 (betaFieldD) on source
    const r4_beta_v2_source = await testTransformer.mut8({
        ibGib: r4_beta_v1_graftPoint,
        in: 'source',
        strField: 'betaFieldD',
        name: 'r4_beta_v2_source',
    });
    // #endregion r4 source edits
    // #region r4 dest edits
    // Retrieve alpha R3 graft point from dest
    const resGet_r4_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
    const r4_alpha_v4_graftPoint_fromDest = resGet_r4_alpha_dest.ibGibs[0];
    // Mutate alpha v5 (fieldG) from R3 graft point
    const r4_alpha_v5_dest = await testTransformer.mut8({
        ibGib: r4_alpha_v4_graftPoint_fromDest,
        in: 'dest',
        strField: 'fieldG',
        name: 'r4_alpha_v5_dest',
        comments_snake_plus_CamelCase: 'postGraft2',
    });
    // Retrieve beta R3 graft point from dest
    const resGet_r4_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
    const r4_beta_v1_graftPoint_fromDest = resGet_r4_beta_dest.ibGibs[0];
    // Mutate beta v2 (betaFieldC) on dest
    const r4_beta_v2_dest = await testTransformer.mut8({
        ibGib: r4_beta_v1_graftPoint_fromDest,
        in: 'dest',
        strField: 'betaFieldC',
        name: 'r4_beta_v2_dest',
    });
    // #endregion r4 dest edits
    await respecfully(sir, `r4 verify pre`, async () => {
        await ifWe(sir, 'dest has alpha and beta post-R3 tips', async () => {
            const destKV = await receiverCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r4_alpha_v4_graftPoint_fromDest, r4_beta_v1_graftPoint_fromDest]
            });
            iReckon(sir, !!destKV[alpha_tjpAddr]).isGonnaBeTruthy();
            iReckon(sir, !!destKV[beta_tjpAddr]).isGonnaBeTruthy();
        });
    });
    const peerR4 = await newTestPeer();
    const r4_syncSaga = await senderCoordinator.sync({
        peer: peerR4,
        localSpace: sourceSpace,
        metaspace,
        domainIbGibs: [r4_alpha_v7_source.ibGib, r4_gamma_v0_source.ibGib, r4_beta_v2_source.ibGib],
        conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        senderIdentity: senderIdentityLatestSource,
        fnSenderSecret: async () => SENDER_SECRET,
    });
    await r4_syncSaga.done;
    await respecfully(sir, `r4 verify post`, async () => {
        const gamma_tjpAddr = getTjpAddr({ ibGib: r4_gamma_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
        const r4_alpha_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const r4_alpha_source_tipAddr = r4_alpha_sourceKV[alpha_tjpAddr];
        const r4_alpha_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const r4_alpha_dest_tipAddr = r4_alpha_destKV[alpha_tjpAddr];
        const r4_beta_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
        const r4_beta_source_tipAddr = r4_beta_sourceKV[beta_tjpAddr];
        const r4_beta_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
        const r4_beta_dest_tipAddr = r4_beta_destKV[beta_tjpAddr];
        const r4_gamma_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r4_gamma_v0_source.ibGib] });
        const r4_gamma_source_tipAddr = r4_gamma_sourceKV[gamma_tjpAddr];
        const r4_gamma_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r4_gamma_v0_source.ibGib] });
        const r4_gamma_dest_tipAddr = r4_gamma_destKV[gamma_tjpAddr];
        await ifWe(sir, 'r4 tip addrs match (alpha, beta, gamma)', async () => {
            iReckon(sir, r4_alpha_source_tipAddr).asTo('alpha tip').isGonnaBe(r4_alpha_dest_tipAddr);
            iReckon(sir, r4_beta_source_tipAddr).asTo('beta tip').isGonnaBe(r4_beta_dest_tipAddr);
            iReckon(sir, r4_gamma_source_tipAddr).asTo('gamma tip').isGonnaBe(r4_gamma_dest_tipAddr);
        });
        const resGet_r4_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r4_alpha_source_tipAddr });
        const r4_alpha_tipIbGib = resGet_r4_alpha_tip.ibGibs[0];
        const resGet_r4_beta_tip = await getFromSpace({ space: sourceSpace, addr: r4_beta_source_tipAddr });
        const r4_beta_tipIbGib = resGet_r4_beta_tip.ibGibs[0];
        await ifWe(sir, 'r4 alpha has complete chain of edits and gamma relation', async () => {
            const r4_source_alpha_v5_mut8Info = r4_alpha_v5_source.infos[0];
            const r4_source_alpha_v7_mut8Info = r4_alpha_v7_source.infos[0];
            const r4_dest_alpha_mut8Info = r4_alpha_v5_dest.infos[0];
            iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v5_mut8Info.key]).isGonnaBe(r4_source_alpha_v5_mut8Info.value);
            iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v7_mut8Info.key]).isGonnaBe(r4_source_alpha_v7_mut8Info.value);
            iReckon(sir, r4_alpha_tipIbGib.data[r4_dest_alpha_mut8Info.key]).isGonnaBe(r4_dest_alpha_mut8Info.value);
            const gammaAddr = getIbGibAddr({ ibGib: r4_gamma_v0_source.ibGib });
            const alphaRel8ns = r4_alpha_tipIbGib.rel8ns?.[TEST_REL8N_NAME] || [];
            iReckon(sir, alphaRel8ns.includes(gammaAddr)).isGonnaBeTrue();
        });
        await ifWe(sir, 'r4 beta has all edits', async () => {
            const r4_source_beta_mut8Info = r4_beta_v2_source.infos[0];
            const r4_dest_beta_mut8Info = r4_beta_v2_dest.infos[0];
            iReckon(sir, r4_beta_tipIbGib.data[r4_source_beta_mut8Info.key]).isGonnaBe(r4_source_beta_mut8Info.value);
            iReckon(sir, r4_beta_tipIbGib.data[r4_dest_beta_mut8Info.key]).isGonnaBe(r4_dest_beta_mut8Info.value);
        });
        await ifWe(sir, 'r4 gamma synced with deps', async () => {
            const [gamma_dest] = await getIbGibsFromCache_fallbackToSpaces({
                addrs: [r4_gamma_v0_source.addr],
                space: destSpace,
            });
            iReckon(sir, gamma_dest).asTo('gamma exists in dest').isGonnaBeTruthy();
        });
        await ifWe(sir, 'sessionIdentity evolved for Round 4', async () => {
            const latestS = peerR4.currentSessionIdentity;
            iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
            if (latestS) {
                iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
            }
        });
    });
    // #endregion Round 4: Chain Edits After Graft
});
//# sourceMappingURL=sync-conflict-adv-multitimelines.withid.respec.mjs.map