import { test } from '@japa/runner'
import { assert } from '@esm-bundle/chai'
import { Property } from '../../../src/models/Property.js'
import { HeadersArray } from '../../../src/models/HeadersArray.js'
import { Headers } from '../../../src/lib/headers/Headers.js'

test('HeadersArray.from() | initializes the array with the properties', () => {
  const p1 = Property.String('a', 'b', true).toJSON()
  const p2 = Property.String('c', 'd', false).toJSON()
  const arr = HeadersArray.from([p1, p2])
  assert.lengthOf(arr, 2, 'has 2 elements')
  assert.equal(arr[0].name, 'a', 'has item #1 name')
  assert.equal(arr[0].value, 'b', 'has item #1 value')
  assert.equal(arr[0].enabled, true, 'has item #1 enabled')
  assert.equal(arr[1].name, 'c', 'has item #2 name')
  assert.equal(arr[1].value, 'd', 'has item #2 value')
  assert.equal(arr[1].enabled, false, 'has item #2 enabled')
  assert.instanceOf(arr[0], Property, 'items are instances of Property')
})

test('HeadersArray.from() | initializes the array from a set', () => {
  const p1 = Property.String('a', 'b', true).toJSON()
  const p2 = Property.String('c', 'd', false).toJSON()
  const arr = HeadersArray.from([...new Set([p1, p2])])
  assert.lengthOf(arr, 2, 'has 2 elements')
  assert.instanceOf(arr[0], Property, 'items are instances of Property')
})

test('HeadersArray.fromHeaders() | initializes all items', () => {
  const input = 'My_Test: header\n# disabled: value\nAbCd: Test'
  const arr = HeadersArray.fromHeaders(input)
  assert.lengthOf(arr, 3, 'has 3 elements')
  assert.equal(arr[0].enabled, true, 'has item #1 enabled')
  assert.equal(arr[1].enabled, false, 'has item #2 enabled')
  assert.equal(arr[2].enabled, true, 'has item #3 enabled')

  assert.equal(arr[0].type, 'string', 'has item #1 type')
  assert.equal(arr[1].type, 'string', 'has item #2 type')
  assert.equal(arr[2].type, 'string', 'has item #3 type')

  assert.instanceOf(arr[0], Property, 'items are instances of Property')
})

test('HeadersArray#toString() | returns an HTTP string', () => {
  const input = 'My_Test: header\nAbCd: Test'
  const instance = HeadersArray.fromHeaders(input)
  const result = instance.toString()
  assert.equal(result, input)
})

test('HeadersArray#toString() | does not include disabled items', () => {
  const input = 'My_Test: header\nAbCd: Test'
  const str = 'My_Test: header\nAbCd: Test\n#disabled: value'
  const instance = HeadersArray.fromHeaders(str)
  const result = instance.toString()
  assert.equal(result, input)
})

test('HeadersArray#toRawString() | returns an HTTP string', () => {
  const input = 'My_Test: header\n# disabled: value\nAbCd: Test'
  const instance = HeadersArray.fromHeaders(input)
  const result = instance.toRawString()
  assert.equal(result, input)
})

test('HeadersArray#toHeaders() | returns an instance of headers', () => {
  const input = 'My_Test: header\n# disabled: value\nAbCd: Test'
  const instance = HeadersArray.fromHeaders(input)
  const result = instance.toHeaders()
  assert.instanceOf(result, Headers, 'is the instance of headers')
})

test('HeadersArray#toHeaders() | has enabled properties', () => {
  const input = 'My_Test: header\n# disabled: value\nAbCd: Test'
  const instance = HeadersArray.fromHeaders(input)
  const result = instance.toHeaders()
  assert.equal(result.get('My_Test'), 'header')
  assert.equal(result.get('AbCd'), 'Test')
})

test('HeadersArray#toHeaders() | has disabled properties', () => {
  const input = 'My_Test: header\n# disabled: value\nAbCd: Test'
  const instance = HeadersArray.fromHeaders(input)
  const result = instance.toHeaders()
  assert.equal(result._map['disabled'].value, 'value')
})
