import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from '@jest/globals'
import mockfs from 'mock-fs'
import request from 'supertest'
import { createApp } from '../src/createApp'
import { createMockServer, generateSimpleViteManifest, getRandomPort } from './util.js'

describe('Responses contain custom headers', () => {
  let app
  let mockserver
  const port = getRandomPort()

  beforeAll(() => {
    mockfs({
      './config/manifests': {
        'urls.yaml': `manifests:
          - http://localhost:${port}/manifest.json`
      }
    })
    app = createApp()
  })

  afterAll(() => {
    mockfs.restore()
  })

  beforeEach(async () => {
    mockserver = await createMockServer({ port })
    mockserver.respondWith({
      '/manifest.json': generateSimpleViteManifest({
        'example.js': {}
      }),
      '/example.js': (req, res) => res.setHeader('content-type', 'application/javascript').status(200).send('this is example'),
      '/meta.json': { name: 'sample-service', version: '1.0' }
    })
    await request(app).get('/ready')
  })

  afterEach(() => {
    mockserver.close()
    delete process.env.APP_VERSION
    delete process.env.BUILD_TIMESTAMP
    delete process.env.CI_COMMIT_SHA
  })

  it('has own metadata', async () => {
    process.env.APP_VERSION = '4.2'
    process.env.BUILD_TIMESTAMP = '0123456789'
    process.env.CI_COMMIT_SHA = '0123456789abcdef'

    const response = await request(app).get('/meta')
    expect(response.statusCode).toBe(200)
    expect(response.body).toContainEqual({
      id: 'manifest-service',
      name: 'Manifest Service',
      buildDate: '0123456789',
      commitSha: '0123456789abcdef',
      version: '4.2'
    })
  })

  it('has metadata from another ui service if available', async () => {
    const response = await request(app).get('/meta')
    expect(response.statusCode).toBe(200)
    expect(response.body).toContainEqual({
      name: 'sample-service',
      version: '1.0'
    })
  })

  it('does not have metadata from ui service when unavailable', async () => {
    await mockserver.close()

    const response = await request(app).get('/meta')
    expect(response.statusCode).toBe(200)
    expect(response.body).not.toContain({
      name: 'sample-service',
      version: '1.0'
    })
  })
})