import { test } from '@japa/runner'
import { File, ThingKind, IFile } from '../../../../src/index.js'

test.group('File.new()', (group) => {
  let file: File
  let base: IFile
  group.each.setup(async () => {
    file = new File()
    base = {
      kind: 'test-kind',
      info: {
        kind: ThingKind,
        name: 'hello',
        description: 'a desc',
      },
      key: '123',
      parents: ['p1'],
      permissionIds: ['pr1'],
      permissions: [
        {
          addingUser: '123',
          key: '123',
          kind: 'Core#Permission',
          granteeId: '345',
          role: 'commenter',
          type: 'organization',
          itemId: '678',
          depth: 0,
          sourceRule: 'creator_default_owner',
        },
      ],
      lastModified: { byMe: false, time: 1, user: 'u1', name: 'mod-test' },
      labels: ['l1'],
      deleted: true,
      deletedInfo: { byMe: false, time: 2, user: 'u2', name: 'delete-test' },
      iconColor: '#c00',
    }
  })

  test('sets the key', ({ assert }) => {
    file.new({ ...base })
    assert.equal(file.key, '123')
  })

  test('sets a new key when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'key')
    file.new(iFile)
    assert.typeOf(file.key, 'string')
  })

  test('sets the kind', ({ assert }) => {
    file.new({ ...base })
    assert.equal(file.kind, 'test-kind')
  })

  test('sets the info', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.info.toJSON(), base.info)
  })

  test('sets a new info when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'info')
    file.new(iFile)
    assert.typeOf(file.info, 'EventTarget')
    assert.equal(file.info.name, '')
  })

  test('sets the parents', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.parents, ['p1'])
  })

  test('sets default parents when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'parents')
    file.new(iFile)
    assert.deepEqual(file.parents, [])
  })

  test('sets the permissionIds', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.permissionIds, ['pr1'])
  })

  test('sets default permissionIds when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'permissionIds')
    file.new(iFile)
    assert.deepEqual(file.permissionIds, [])
  })

  test('sets the lastModified', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.lastModified, base.lastModified)
  })

  test('sets a default lastModified when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'lastModified')
    file.new(iFile)
    assert.typeOf(file.lastModified, 'object')
    assert.equal(file.lastModified.time, 0)
  })

  test('sets the permissions', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.permissions, base.permissions)
  })

  test('sets a default permissions when missing', ({ assert }) => {
    const iFile = { ...base }
    Reflect.deleteProperty(iFile, 'permissions')
    file.new(iFile)
    assert.deepEqual(file.permissions, [])
  })

  test('sets the deleted', ({ assert }) => {
    file.new({ ...base })
    assert.equal(file.deleted, base.deleted)
  })

  test('clears deleted when missing', ({ assert }) => {
    const iFile = { ...base }
    file.new(iFile)
    Reflect.deleteProperty(iFile, 'deleted')
    file.new(iFile)
    assert.isFalse(file.deleted)
  })

  test('sets the deletedInfo with deleted', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.deletedInfo, base.deletedInfo)
  })

  test('clears deletedInfo when not deleted', ({ assert }) => {
    const iFile = { ...base }
    file.new(iFile)
    Reflect.deleteProperty(iFile, 'deleted')
    file.new(iFile)
    assert.isUndefined(file.deletedInfo)
  })

  test('sets the labels', ({ assert }) => {
    file.new({ ...base })
    assert.deepEqual(file.labels, base.labels)
  })

  test('clears labels when not set', ({ assert }) => {
    const iFile = { ...base }
    file.new(iFile)
    Reflect.deleteProperty(iFile, 'labels')
    file.new(iFile)
    assert.isUndefined(file.labels)
  })

  test('sets the iconColor', ({ assert }) => {
    file.new({ ...base })
    assert.equal(file.iconColor, base.iconColor)
  })

  test('clears iconColor when not set', ({ assert }) => {
    const iFile = { ...base }
    file.new(iFile)
    Reflect.deleteProperty(iFile, 'iconColor')
    file.new(iFile)
    assert.isUndefined(file.iconColor)
  })
})
