import { test } from '@japa/runner'
import { HttpProject, IProject, Project, ProjectKind, ThingKind } from '../../../../src/index.js'

test.group('Project.fromProject()', () => {
  test('sets the kind', ({ assert }) => {
    const p1 = HttpProject.fromName('p1')
    const result = Project.fromProject(p1)
    assert.equal(result.kind, ProjectKind)
  })

  test('sets the name', ({ assert }) => {
    const p1 = HttpProject.fromName('p1')
    const result = Project.fromProject(p1)
    assert.equal(result.info.name, 'p1')
  })

  test('sets the key', ({ assert }) => {
    const p1 = HttpProject.fromName('p1')
    const result = Project.fromProject(p1)
    assert.equal(result.key, p1.key)
  })

  test('respects schema instead of instance', ({ assert }) => {
    const p1 = HttpProject.fromName('p1')
    const result = Project.fromProject(p1.toJSON())
    assert.equal(result.info.name, 'p1')
  })
})

test.group('Project.fromName()', () => {
  test('creates project from a name', ({ assert }) => {
    const project = Project.fromName('test')
    assert.equal(project.info.name, 'test')
    assert.equal(project.kind, ProjectKind)
  })
})

test.group('Project.constructor()', () => {
  test('creates project from a name', ({ assert }) => {
    const project = Project.fromName('test')
    assert.equal(project.info.name, 'test')
    assert.equal(project.kind, ProjectKind)
  })

  test('creates a default project', ({ assert }) => {
    const result = new Project()
    assert.equal(result.kind, ProjectKind)
    assert.typeOf(result.key, 'string')
    assert.typeOf(result.lastModified, 'object')
  })

  test('creates a project from the schema values', ({ assert }) => {
    const schema: IProject = {
      kind: ProjectKind,
      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: 0, user: 'id', name: 'test' },
      labels: ['l1'],
    }
    const result = new Project(schema)
    assert.equal(result.kind, ProjectKind)
    assert.equal(result.info.name, 'hello')
    assert.equal(result.key, '123')
    assert.deepEqual(result.parents, ['p1'])
    assert.deepEqual(result.permissionIds, ['pr1'])
    assert.typeOf(result.permissions, 'array')
    assert.deepEqual(result.lastModified, schema.lastModified)
    assert.deepEqual(result.labels, ['l1'])
  })

  test('creates a project from the JSON schema string', ({ assert }) => {
    const schema: IProject = {
      kind: ProjectKind,
      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: 0, user: 'id', name: 'test' },
    }
    const result = new Project(JSON.stringify(schema))
    assert.equal(result.kind, ProjectKind)
    assert.equal(result.info.name, 'hello')
    assert.equal(result.key, '123')
    assert.deepEqual(result.lastModified, schema.lastModified)
  })

  test('throws when invalid schema', ({ assert }) => {
    assert.throws(() => {
      new Project(
        JSON.stringify({
          name: 'a name',
        })
      )
    })
  })
})
