import { test } from '@japa/runner'
import { AmfLoader } from '../AmfLoader.js'
import { AmfSerializer } from '../../../../src/amf/AmfSerializer.js'
import type { IAmfDocument, IAmfServer } from '../../../../src/amf/definitions/Amf.js'
import { AmfNamespace } from '../../../../src/amf/definitions/Namespace.js'

const loader = new AmfLoader()
let api: IAmfDocument
let serializer: AmfSerializer
let servers: IAmfServer[]

test.group('OAS 3', (group) => {
  group.setup(async () => {
    api = await loader.getGraph('oas-3-api')
    serializer = new AmfSerializer(api)
    servers = loader.lookupServers(api)!
  })

  test('returns a server object', ({ assert }) => {
    const result = serializer.server(servers[3])
    assert.typeOf(result, 'object', 'returns an object')
    assert.include(result.types, AmfNamespace.aml.vocabularies.apiContract.Server, 'has the server type')
    assert.typeOf(result.sourceMaps, 'object', 'has source maps')
  })

  test('has the id', ({ assert }) => {
    const result = serializer.server(servers[3])
    assert.typeOf(result.id, 'string')
  })

  test('has the url', ({ assert }) => {
    const result = serializer.server(servers[3])
    assert.equal(result.url, 'https://{username}.gigantic-server.com:{port}/{basePath}')
  })

  test('has the variables', ({ assert }) => {
    const result = serializer.server(servers[3])
    assert.typeOf(result.variables, 'array', 'has the variables property')
    assert.lengthOf(result.variables, 3, 'has all variables')
    const [v1] = result.variables
    assert.typeOf(v1, 'object', 'the variable is an object')
    assert.include(v1.types, AmfNamespace.aml.vocabularies.apiContract.Parameter, 'has the Parameter type')
  })

  test('has the description', ({ assert }) => {
    const result = serializer.server(servers[1])
    assert.equal(result.description, 'Staging server')
  })
})

test.group('Async API', (group) => {
  group.setup(async () => {
    api = await loader.getGraph('async-api')
    serializer = new AmfSerializer(api)
    servers = loader.lookupServers(api)!
  })

  test('returns the server object', ({ assert }) => {
    const result = serializer.server(servers[0])
    assert.typeOf(result, 'object', 'returns an object')
    assert.include(result.types, AmfNamespace.aml.vocabularies.apiContract.Server, 'has the server type')
    assert.typeOf(result.sourceMaps, 'object', 'has source maps')
  })

  test('has the protocol info', ({ assert }) => {
    const result = serializer.server(servers[0])
    assert.equal(result.protocol, 'amqp', 'has the protocol')
    assert.equal(result.protocolVersion, '1.0.0', 'has the protocolVersion')
  })

  test('has the security', ({ assert }) => {
    const result = serializer.server(servers[0])
    assert.typeOf(result.security, 'array', 'has the security')
    assert.lengthOf(result.security!, 2, 'has all security')
    const [security] = result.security!
    assert.lengthOf(security.schemes, 1, 'has the security.schema')
  })
})
