import { test } from '@japa/runner'
import { DataDomain } from '../../../src/modeling/DataDomain.js'

test.group('DataDomain - clone', () => {
  test('clones a data domain shallowly', ({ assert }) => {
    const domain = new DataDomain()
    const ns = domain.addNamespace({ key: 'ns1' })
    const model = ns.addModel({ key: 'model1' })
    model.addEntity({ key: 'entity1' })

    const cloned = domain.clone()

    assert.notStrictEqual(cloned, domain)
    assert.deepEqual(cloned.toJSON(), domain.toJSON())

    // ensure changes to clone don't affect original
    const clonedNs = cloned.findNamespace('ns1')
    assert.isDefined(clonedNs)
    clonedNs!.addModel({ key: 'model2' })

    assert.isUndefined(domain.findModel('model2'))
  })

  test('clones a data domain with dependencies', ({ assert }) => {
    const parentDomain = new DataDomain({ key: 'parent' })
    parentDomain.addNamespace({ key: 'parentNs' })

    const childDomain = new DataDomain({ key: 'child' }, [parentDomain])
    childDomain.addNamespace({ key: 'childNs' })

    // Test clone
    const childClone = childDomain.clone()

    assert.notStrictEqual(childClone, childDomain)
    assert.deepEqual(childClone.toJSON(), childDomain.toJSON())

    assert.equal(childClone.dependencies.size, 1)
    const clonedParent = childClone.dependencies.get('parent')
    assert.isDefined(clonedParent)
    assert.notStrictEqual(clonedParent, parentDomain) // It should be a clone
    assert.deepEqual(clonedParent!.toJSON(), parentDomain.toJSON())

    // ensure they function like normal independent objects
    clonedParent!.addNamespace({ key: 'parentNs2' })
    assert.isUndefined(parentDomain.findNamespace('parentNs2'))
  })
})
