/**
 * test/test_visitor.ets
 *
 * Test Visitor pattern V2.0 implementation
 */

import { Person } from './Person'
import { Address } from './Address'

// Test 1: Create and serialize
console.log('=== Test 1: Create and Serialize ===')

const person = Person.create({
  name: 'Alice',
  age: 30,
  emails: ['alice@example.com', 'alice@work.com'],
  address: {
    street: '123 Main St',
    city: 'New York',
    zipCode: '10001'
  }
})

console.log('Person created:', person)

const binary = person.toBinary()
console.log('Binary length:', binary.length)
console.log('Binary (hex):', Array.from(binary).map(b => b.toString(16).padStart(2, '0')).join(' '))

// Test 2: Deserialize
console.log('\n=== Test 2: Deserialize ===')

const person2 = Person.fromBinary(binary)
console.log('Deserialized person:', person2)
console.log('Name:', person2.name)
console.log('Age:', person2.age)
console.log('Emails:', person2.emails)
console.log('Address.city:', person2.address?.city)

// Test 3: JSON serialization
console.log('\n=== Test 3: JSON Serialization ===')

const json = person.toJson()
console.log('JSON:', JSON.stringify(json, null, 2))

// Test 4: Clone
console.log('\n=== Test 4: Clone ===')

const cloned = person.clone()
console.log('Cloned:', cloned)
console.log('Are they equal?', person.equals(cloned))

// Test 5: Merge
console.log('\n=== Test 5: Merge ===')

const person3 = Person.create({ name: 'Alice', age: 30 })
const update = Person.create({ age: 31, emails: ['alice@new.com'] })
person3.mergeFrom(update)

console.log('After merge:')
console.log('  Name:', person3.name)  // Should be 'Alice'
console.log('  Age:', person3.age)    // Should be 31
console.log('  Emails:', person3.emails)  // Should have 'alice@new.com'

// Test 6: Validation
console.log('\n=== Test 6: Validation ===')

const validPerson = Person.create({ name: 'Bob', age: 25 })
console.log('Valid person:', validPerson.isValid())
console.log('Validation error:', validPerson.validate())

// Test 7: Clear and isEmpty
console.log('\n=== Test 7: Clear and isEmpty ===')

const person4 = Person.create({ name: 'Charlie' })
console.log('Is empty before clear?', person4.isEmpty())
person4.clear()
console.log('Is empty after clear?', person4.isEmpty())

// Test 8: Builder pattern
console.log('\n=== Test 8: Builder Pattern ===')

const person5 = Person.build(p => {
  p.name = 'David'
  p.age = 35
  p.emails.push('david@example.com')
  p.address = Address.create({
    street: '456 Oak Ave',
    city: 'San Francisco'
  })
})

console.log('Built person:', person5.name, person5.age)

console.log('\n✅ All tests completed!')