package dev.ulfrx.recipe

import dev.ulfrx.recipe.auth.PrincipalResolver
import dev.ulfrx.recipe.auth.configureAuthentication
import dev.ulfrx.recipe.auth.meRoute
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.netty.EngineMain
import io.ktor.server.plugins.calllogging.CallLogging
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.request.httpMethod
import io.ktor.server.request.path
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import kotlinx.serialization.Serializable

fun main(args: Array<String>): Unit = EngineMain.main(args)

@Serializable
private data class Health(
    val status: String,
)

fun Application.module() {
    install(CallLogging) {
        // Method + path + status only — never headers (D-23). Ktor 3.4.1's CallLoggingConfig
        // doesn't expose a header-redaction API, so the only safe approach is to omit header
        // data from the format entirely. Bearer tokens never reach the log.
        format { call ->
            "${call.request.httpMethod.value} ${call.request.path()} -> ${call.response.status()?.value ?: "-"}"
        }
    }
    install(ContentNegotiation) {
        json()
    }
    configureAuthentication()
    Database.migrate(this)
    Database.connect(this)
    configureRouting(PrincipalResolver())
}

fun Application.configureRouting(principalResolver: PrincipalResolver = PrincipalResolver()) {
    routing {
        get("/health") {
            call.respond(Health(status = "ok"))
        }
        meRoute(principalResolver)
    }
}
