import { test } from '@japa/runner'
import { DataDomain, DomainAssociation, DomainProperty } from '../../../src/index.js'

test.group('DomainEntity.listFields()', () => {
  test('lists all fields (properties and associations) of this entity', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    const property1 = entity.addProperty()
    const association1 = entity.addAssociation()
    const fields = [...entity.listFields()]
    assert.lengthOf(fields, 2)
    assert.deepInclude(fields, property1)
    assert.deepInclude(fields, association1)
  })

  test('returns an empty array if there are no fields', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    const fields = [...entity.listFields()]
    assert.lengthOf(fields, 0)
  })

  test('returns only properties and associations', ({ assert }) => {
    const root = new DataDomain()
    const m1 = root.addModel()
    const e1 = m1.addEntity()
    const e2 = m1.addEntity()
    const p1 = e1.addProperty()
    e1.addParent(e2.key)
    const association1 = e1.addAssociation()

    const fields = [...e1.listFields()]
    assert.lengthOf(fields, 2)
    assert.deepInclude(fields, p1)
    assert.deepInclude(fields, association1)
  })

  test('fields in the list are of type DomainProperty or DomainAssociation', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    entity.addProperty()
    entity.addAssociation()
    const fields = [...entity.listFields()]
    assert.instanceOf(fields[0], DomainProperty)
    assert.instanceOf(fields[1], DomainAssociation)
  })

  test('lists fields in the order they were added', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    const property1 = entity.addProperty()
    const association1 = entity.addAssociation()
    const property2 = entity.addProperty({ key: 'property2' })
    const association2 = entity.addAssociation()

    const fields = [...entity.listFields()]
    assert.deepEqual(fields, [property1, association1, property2, association2])
  })

  test('lists fields when there are no fields', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    const fields = [...entity.listFields()]
    assert.deepEqual(fields, [])
  })

  test('lists fields when fields array is empty', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    entity.fields = []
    const fields = [...entity.listFields()]
    assert.deepEqual(fields, [])
  })
})

test.group('DomainEntity.hasFields()', () => {
  test('returns true if the entity has any fields (properties or associations)', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    entity.addProperty()
    assert.isTrue(entity.hasFields())
  })

  test('returns true if the entity has any associations', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    entity.addAssociation()
    assert.isTrue(entity.hasFields())
  })

  test('returns false if the entity has no fields', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    assert.isFalse(entity.hasFields())
  })

  test('returns false if the entity has an empty fields array', ({ assert }) => {
    const dataDomain = new DataDomain()
    const model = dataDomain.addModel()
    const entity = model.addEntity()
    entity.fields = []
    assert.isFalse(entity.hasFields())
  })
})
