import 'dotenv/config'
import Fastify from 'fastify'
import cors from '@fastify/cors'
import jwt from '@fastify/jwt'
import websocket from '@fastify/websocket'
import multipart from '@fastify/multipart'
import { authRoutes } from './routes/auth.js'
import { integrationRoutes } from './routes/integrations.js'
import { bookmarkRoutes } from './routes/bookmarks.js'
import { eventRoutes } from './routes/events.js'
import { terminalRoutes } from './routes/terminal.js'
import { tunnelRoutes } from './routes/tunnels.js'
import { fileRoutes } from './routes/files.js'
import { dockerRoutes, dockerExecRoutes } from './routes/docker.js'
import { guacamoleRoutes } from './routes/guacamole.js'
import { metricsRoutes } from './routes/metrics.js'
import { transferRoutes } from './routes/transfer.js'
import { dataRoutes } from './routes/data.js'
import { startAutoStartTunnels } from './tunnels/manager.js'

const JWT_SECRET = process.env.ARCHNEST_JWT_SECRET
if (!JWT_SECRET) {
  throw new Error('ARCHNEST_JWT_SECRET env var is required')
}

const app = Fastify({ logger: true })

await app.register(cors, { origin: process.env.ARCHNEST_CORS_ORIGIN ?? true })
await app.register(jwt, { secret: JWT_SECRET })
await app.register(websocket)
await app.register(multipart, { limits: { fileSize: 1024 * 1024 * 1024 } })

app.decorate('authenticate', async function (req, reply) {
  try {
    await req.jwtVerify()
  } catch {
    reply.code(401).send({ error: 'Unauthorized' })
  }
})

await app.register(authRoutes)
await app.register(integrationRoutes)
await app.register(bookmarkRoutes)
await app.register(eventRoutes)
await app.register(terminalRoutes)
await app.register(tunnelRoutes)
await app.register(fileRoutes)
await app.register(dockerRoutes)
await app.register(dockerExecRoutes)
await app.register(guacamoleRoutes)
await app.register(metricsRoutes)
await app.register(transferRoutes)
await app.register(dataRoutes)

app.get('/api/health', async () => ({ ok: true }))

const port = Number(process.env.PORT ?? 4000)
app.listen({ port, host: '0.0.0.0' }).catch((err) => {
  app.log.error(err)
  process.exit(1)
})

startAutoStartTunnels()
