import { test } from '@japa/runner'
import { AccessRule, type AccessRuleSchema } from '../../../../src/modeling/index.js'

test.group('AccessRule', () => {
  test('initializes with default values', ({ assert }) => {
    const rule = new AccessRule()
    assert.equal(rule.type, '')
  }).tags(['@modeling', '@access-rule'])

  test('initializes with provided values', ({ assert }) => {
    const schema: AccessRuleSchema = { type: 'public' }
    const rule = new AccessRule(schema)
    assert.equal(rule.type, 'public')
  }).tags(['@modeling', '@access-rule'])

  test('serializes to JSON', ({ assert }) => {
    const rule = new AccessRule({ type: 'authenticated' })
    const json = rule.toJSON()
    assert.deepEqual(json, { type: 'authenticated' })
  }).tags(['@modeling', '@access-rule'])

  test('notifies change', async ({ assert }) => {
    const rule = new AccessRule({ type: 'public' })
    let notified = false
    rule.addEventListener('change', () => {
      notified = true
    })

    rule.notifyChange()
    assert.isTrue(notified)
  }).tags(['@modeling', '@access-rule'])

  test('toJSON returns safe copy (immutability)', ({ assert }) => {
    const rule = new AccessRule({ type: 'public' })
    const json = rule.toJSON()

    // Modify JSON (simulate runtime mutation)
    json.type = 'changed'

    assert.equal(rule.type, 'public')
  }).tags(['@modeling', '@access-rule', '@immutability'])
})
