import { test } from '@japa/runner'
import { DataTestHelper } from './DataTestHelper.js'
import { ArcExportObject, ArcDexieTransformer } from '../../../src/legacy.js'
import dexieData from './data/dexie-data-export.json' with { type: 'json' }
import dexieHistoryData from './data/dexie-history-export.json' with { type: 'json' }
import dexieSavedData from './data/dexie-saved-export.json' with { type: 'json' }

test.group('Dexie export', (group) => {
  let result: ArcExportObject
  group.setup(async () => {
    const transformer = new ArcDexieTransformer(structuredClone(dexieData))
    result = await transformer.transform()
  })

  test('normalizes the data', ({ assert }) => {
    assert.typeOf(result, 'object')
  })

  test('has export object properties', ({ assert }) => {
    assert.typeOf(result.createdAt, 'string')
    assert.equal(result.version, 'unknown')
    assert.equal(result.kind, 'ARC#Import')
    assert.typeOf(result.projects, 'array')
    assert.typeOf(result.requests, 'array')
    assert.typeOf(result.history, 'array')
  })

  test('has 2 projects', ({ assert }) => {
    assert.lengthOf(result.projects!, 2)
  })

  test('has empty history', ({ assert }) => {
    assert.lengthOf(result.history!, 0)
  })

  test('has 6 requests', ({ assert }) => {
    assert.lengthOf(result.requests!, 6)
  })

  test('produces valid request objects', ({ assert }) => {
    DataTestHelper.assertRequestObject(result.requests![0], assert)
    DataTestHelper.assertRequestObject(result.requests![3], assert)
    DataTestHelper.assertRequestObject(result.requests![5], assert)
  })

  test('sets values on the requests', ({ assert }) => {
    let request = result.requests![0]
    assert.equal(request.url, 'http://localhost:8080/url2')
    assert.equal(request.method, 'GET')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506365775233)
    assert.equal(request.name, 'test-request')
    assert.equal(request.type, 'saved')

    request = result.requests![3]
    assert.equal(request.url, 'http://onet.pl/test')
    assert.equal(request.method, 'GET')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506365939968)
    assert.equal(request.name, 'Other endpoint')
    assert.equal(request.type, 'saved')

    request = result.requests![5]
    assert.equal(request.url, 'http://second-project.com')
    assert.equal(request.method, 'PUT')
    assert.equal(request.headers, 'x-test: headers')
    assert.equal(request.payload, 'test-payload')
    assert.equal(request.created, 1506367353657)
    assert.equal(request.name, 'second-project-request')
    assert.equal(request.type, 'saved')
  })

  test('produces valid project objects', ({ assert }) => {
    DataTestHelper.assertProjectObject(result.projects![0], assert)
    DataTestHelper.assertProjectObject(result.projects![1], assert)
  })

  test('Project values are set', ({ assert }) => {
    let project = result.projects![0]
    assert.equal(project.name, 'Project name', 'name is set')
    assert.equal(project.created, 1506365878724, 'created is set')
    assert.strictEqual(project.order, 0, 'order is set')

    project = result.projects![1]
    assert.equal(project.name, 'second-project', 'name is set')
    assert.equal(project.created, 1506367353678, 'created is set')
    assert.strictEqual(project.order, 0, 'order is set')
  })

  test('Associate requests with projects', ({ assert }) => {
    assert.isUndefined(result.requests![0].projects)
    assert.isUndefined(result.requests![1].projects)
    assert.typeOf(result.requests![2].projects![0], 'string')
    assert.typeOf(result.requests![3].projects![0], 'string')
    assert.typeOf(result.requests![4].projects![0], 'string')
    assert.typeOf(result.requests![5].projects![0], 'string')
  })

  test('Project ID is set correctly', ({ assert }) => {
    const p1id = result.projects![0].key
    const p2id = result.projects![1].key
    assert.equal(result.requests![2].projects![0], p1id)
    assert.equal(result.requests![3].projects![0], p1id)
    assert.equal(result.requests![4].projects![0], p1id)
    assert.equal(result.requests![5].projects![0], p2id)
  })

  test('Project has request reference', ({ assert }) => {
    const p1 = result.projects![0]
    const p2 = result.projects![1]
    assert.typeOf(p1.requests, 'array')
    assert.lengthOf(p1.requests!, 4)
    assert.typeOf(p2.requests, 'array')
    assert.lengthOf(p2.requests!, 1)
  })
})

test.group('Dexie history', (group) => {
  let result: ArcExportObject
  group.setup(async () => {
    const transformer = new ArcDexieTransformer(structuredClone(dexieHistoryData))
    result = await transformer.transform()
  })

  test('Normalizes the data', ({ assert }) => {
    assert.typeOf(result, 'object')
  })

  test('History contains 4 entries', ({ assert }) => {
    assert.lengthOf(result.history!, 4)
  })

  test('has valid history objects', ({ assert }) => {
    DataTestHelper.assertHistoryObject(result.history![0], assert)
    DataTestHelper.assertHistoryObject(result.history![1], assert)
    DataTestHelper.assertHistoryObject(result.history![2], assert)
    DataTestHelper.assertHistoryObject(result.history![3], assert)
  })

  test('Request values are set', ({ assert }) => {
    let request = result.history![0]
    assert.equal(request.url, 'http://wp.pl')
    assert.equal(request.method, 'GET')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506366584358)

    request = result.history![2]
    assert.equal(request.url, 'http://google.com')
    assert.equal(request.method, 'PUT')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506365841855)
  })
})

test.group('Dexie saved export', (group) => {
  let result: ArcExportObject
  group.setup(async () => {
    const transformer = new ArcDexieTransformer(structuredClone(dexieSavedData))
    result = await transformer.transform()
  })

  test('Requests contains 2 entries', ({ assert }) => {
    assert.lengthOf(result.requests!, 2)
  })

  test('Request objects are valid', ({ assert }) => {
    DataTestHelper.assertRequestObject(result.requests![0], assert)
    DataTestHelper.assertRequestObject(result.requests![1], assert)
  })

  test('Request values are set', ({ assert }) => {
    let request = result.requests![0]
    assert.equal(request.url, 'http://localhost:8080/url2')
    assert.equal(request.method, 'GET')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506365775233)
    assert.equal(request.name, 'Request in project')
    assert.equal(request.type, 'saved')

    request = result.requests![1]
    assert.equal(request.url, 'http://google.com')
    assert.equal(request.method, 'GET')
    assert.equal(request.headers, '')
    assert.equal(request.payload, '')
    assert.equal(request.created, 1506365826194)
    assert.equal(request.name, 'Regular request')
    assert.equal(request.type, 'saved')
  })
})
