// Add env vars from files
// Note: actual env vars supersede .env file and .env file supersedes .env.defaults file
import { config } from 'dotenv-defaults'
import { logger, timeSinceStartup } from './logger.js'
import { createApp } from './create-app.js'
import { getLatestVersion } from './version.js'
import { configMap } from './configMap.js'
import * as redis from './redis.js'
import lightshipCjs from 'lightship'
import { createMetricsServer } from './metrics.js'
import { warmCache } from './files.js'

config()

const { createLightship } = lightshipCjs
const lightship = await createLightship()

lightship.queueBlockingTask(redis.isReady())
lightship.queueBlockingTask(configMap.load())
lightship.queueBlockingTask(getLatestVersion()
  .then(() => logger.info(`[Health] Check latest version on startup. Time since startup: ${timeSinceStartup()}`)))

const app = await createApp()
const metricsServer = await createMetricsServer()

app.addHook('onReady', () => {
  lightship.signalReady()
})

app.addHook('onReady', () => {
  // don't block the onReady hook
  getLatestVersion()
    .then(version => warmCache({ version }))
    .catch(err => logger.error(err))
})

// Binds and listens for connections on the specified host and port
app.listen({ host: '::', port: Number(process.env.PORT) })

lightship.registerShutdownHandler(async () => {
  logger.info('[Health] Shutting down...')
  if (redis.isEnabled()) {
    await Promise.all([
      redis.client.quit(),
      redis.pubClient.quit(),
      redis.subClient.quit()
    ])
  }
  await app.close()
  await metricsServer.close()
})

process.on('uncaughtException', async err => {
  logger.error(err, 'uncaughtException')
  await lightship.shutdown()
})

process.on('unhandledRejection', async err => {
  logger.error(err, 'unhandledRejection')
  await lightship.shutdown()
})