import { test } from '@japa/runner'
import {
  SemanticType,
  DataSemantics,
  isPropertySemantic,
  SemanticCategory,
  SemanticScope,
  SemanticTiming,
  SemanticOperation,
} from '../../../src/modeling/Semantics.js'

test.group('ClientIPAddress Semantic', () => {
  test('should exist in SemanticType enum', ({ assert }) => {
    assert.equal(SemanticType.ClientIPAddress, 'Semantic#ClientIPAddress')
  })

  test('should exist in DataSemantics registry', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    assert.isDefined(semantic)
    assert.equal(semantic.id, SemanticType.ClientIPAddress)
  })

  test('should be a property semantic', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    assert.isTrue(isPropertySemantic(semantic))
    assert.equal(semantic.scope, SemanticScope.Property)
  })

  test('should have correct display name and description', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    assert.equal(semantic.displayName, 'Client IP Address')
    assert.equal(semantic.description, 'Automatically populated client IP address')
  })

  test('should be in Contact category', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    assert.equal(semantic.category, SemanticCategory.Contact)
  })

  test('should only apply to string data types', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    if (isPropertySemantic(semantic)) {
      assert.deepEqual(semantic.applicableDataTypes, ['string'])
    }
  })

  test('should not have configuration', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    assert.isFalse(semantic.hasConfig)
  })

  test('should have correct runtime configuration', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    const runtime = semantic.runtime

    assert.equal(runtime.timing, SemanticTiming.Before)
    assert.deepEqual(runtime.operations, [SemanticOperation.Create, SemanticOperation.Update])
    assert.equal(runtime.priority, 95) // Low priority, populate after other validations
    assert.equal(runtime.timeoutMs, 100) // Very fast operation
  })

  test('should have correct execution conditions', ({ assert }) => {
    const semantic = DataSemantics[SemanticType.ClientIPAddress]
    const conditions = semantic.runtime.conditions

    assert.isDefined(conditions)
    assert.lengthOf(conditions!, 1)
    assert.equal(conditions![0].expression, 'entity[semantics.ClientIPAddress] == null')
    assert.equal(conditions![0].description, 'Only set IP address if not already provided')
  })
})
