import { test } from '@japa/runner'
import { MatchEmailDomainAccessRule } from '../../../../src/modeling/rules/MatchEmailDomain.js'

test.group('MatchEmailDomainAccessRule', () => {
  test('initializes with default values', ({ assert }) => {
    const rule = new MatchEmailDomainAccessRule()
    assert.equal(rule.type, 'matchEmailDomain')
    assert.deepEqual(rule.domains, [])
  }).tags(['@modeling', '@rule', '@match-email-domain'])

  test('initializes with provided values', ({ assert }) => {
    const domains = ['example.com', 'test.org']
    const rule = new MatchEmailDomainAccessRule({ domains })

    assert.equal(rule.type, 'matchEmailDomain')
    assert.deepEqual(rule.domains, domains)
  }).tags(['@modeling', '@rule', '@match-email-domain'])

  test('constructor copies arrays (immutability)', ({ assert }) => {
    const domains = ['example.com']
    const rule = new MatchEmailDomainAccessRule({ domains })

    // Modify original source
    domains.push('hacker.com')

    assert.deepEqual(rule.domains, ['example.com'])
  }).tags(['@modeling', '@rule', '@match-email-domain', '@immutability'])

  test('toJSON returns valid schema', ({ assert }) => {
    const rule = new MatchEmailDomainAccessRule({ domains: ['example.com'] })
    const json = rule.toJSON()

    // Modify JSON
    json.domains.push('hacker.com')

    assert.equal(json.type, 'matchEmailDomain')
    assert.lengthOf(rule.domains, 1) // Ensure immutability
    assert.equal(rule.domains[0], 'example.com')
  }).tags(['@modeling', '@rule', '@match-email-domain', '@serialization', '@immutability'])

  test('notifies change when domains changes', async ({ assert }) => {
    const rule = new MatchEmailDomainAccessRule()
    let notified = false
    rule.addEventListener('change', () => {
      notified = true
    })

    rule.domains = ['example.com']
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@rule', '@match-email-domain', '@observed'])
})
