import test from 'node:test'
import assert from 'node:assert/strict'
import type { Server } from 'node:http'

import { createShutdownController } from './shutdown.js'
import type { StartupState } from './state.js'

function createStartupState(): StartupState {
  return {
    phase: 'ready',
    core: {
      running: false,
      ready: true,
      attemptCount: 1,
      lastAttemptAt: '',
      lastError: '',
      readyAt: '',
    },
    process: {
      lastUnhandledRejection: null,
      lastUncaughtException: null,
    },
  }
}

test('shutdown closes the HTTP server and database pool', async () => {
  let serverClosed = false
  let databaseClosed = false
  const server = {
    listening: true,
    close(callback: (error?: Error) => void) {
      serverClosed = true
      callback()
    },
  } as unknown as Server
  const controller = createShutdownController(server, createStartupState(), {
    closeDatabase: async () => {
      databaseClosed = true
    },
  })

  await controller.shutdown('test')

  assert.equal(serverClosed, true)
  assert.equal(databaseClosed, true)
  assert.equal(controller.isShutdownStarted(), true)
})

test('shutdown closes the database pool when the server is already stopped', async () => {
  let databaseClosed = false
  const server = {
    listening: false,
    close() {
      throw new Error('close should not be called')
    },
  } as unknown as Server
  const controller = createShutdownController(server, createStartupState(), {
    closeDatabase: async () => {
      databaseClosed = true
    },
  })

  await controller.shutdown('test')

  assert.equal(databaseClosed, true)
})
