import http from 'node:http'
import { randomUUID } from 'node:crypto'
import { handleLiteApi } from './lite/api.mjs'
import { corsAllowHeaders, corsHeaders, isCorsOriginAllowed } from './lite/http.mjs'
import { captureException, logStructured, observeHttpRequest } from './lite/observability.mjs'

const port = Number(process.env.PORT ?? 4000)

const server = http.createServer(async (request, response) => {
  const startedAt = Date.now()
  const requestId = request.headers['x-request-id'] || randomUUID()
  request.requestId = requestId
  response.setHeader('x-request-id', requestId)
  const origin = request.headers.origin || ''
  response.corsOrigin = origin
  if (origin && !isCorsOriginAllowed(origin)) {
    response.writeHead(403, {
      'content-type': 'application/json; charset=utf-8',
    })
    response.end(JSON.stringify({
      error: 'cors_origin_denied',
      message: 'CORS origin is not allowed',
    }))
    return
  }

  if (request.method === 'OPTIONS') {
    response.writeHead(204, {
      ...corsHeaders(origin),
      'access-control-allow-methods': 'GET,POST,PATCH,DELETE,OPTIONS',
      'access-control-allow-headers': corsAllowHeaders,
    })
    response.end()
    return
  }

  try {
    await handleLiteApi(request, response)
  } catch (error) {
    const eventId = await captureException(error, {
      requestId,
      method: request.method,
      route: request.url,
    })
    response.writeHead(500, {
      'content-type': 'application/json; charset=utf-8',
      ...corsHeaders(origin),
    })
    response.end(JSON.stringify({
      error: 'internal_error',
      message: 'Internal server error',
      eventId,
    }))
  } finally {
    const durationMs = Date.now() - startedAt
    observeHttpRequest({
      method: request.method,
      route: request.url?.split('?')[0] || '/',
      statusCode: response.statusCode,
      durationMs,
    })
    logStructured(response.statusCode >= 500 ? 'error' : 'info', 'http_request', {
      requestId,
      method: request.method,
      route: request.url?.split('?')[0] || '/',
      status: response.statusCode,
      durationMs,
    })
  }
})

server.listen(port, () => {
  console.log(`DLBDI backend lite server listening on http://localhost:${port}`)
})
