package com.correx.apps.server

import com.correx.apps.server.health.HealthInspectionService
import com.correx.apps.server.metrics.ToolReliabilityInspectionService
import com.correx.apps.server.routes.providerRoutes
import com.correx.apps.server.routes.sessionRoutes
import com.correx.apps.server.routes.taskRoutes
import com.correx.apps.server.routes.workflowRoutes
import com.correx.apps.server.ws.GlobalStreamHandler
import io.ktor.http.HttpStatusCode
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.plugins.calllogging.CallLogging
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.plugins.statuspages.StatusPages
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import io.ktor.server.websocket.WebSockets
import io.ktor.server.websocket.webSocket
import kotlinx.serialization.json.Json
import org.slf4j.event.Level

fun Application.configureServer(module: ServerModule) {
    install(CallLogging) { level = Level.INFO }

    install(WebSockets)

    install(ContentNegotiation) {
        json(Json { ignoreUnknownKeys = true })
    }

    install(StatusPages) {
        exception<Throwable> { call, cause ->
            call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (cause.message ?: "Internal error")))
        }
    }

    val globalStreamHandler = GlobalStreamHandler(module)
    val healthInspection = HealthInspectionService(module.eventStore)
    val toolReliability = ToolReliabilityInspectionService(module.eventStore)

    routing {
        get("/health") {
            val providerHealth = runCatching { module.providerRegistry.healthCheckAll() }.getOrDefault(emptyMap())
            call.respond(mapOf("status" to "ok", "providers" to providerHealth.size.toString()))
        }

        // observability-spec §4: the recorded health-check report (disk watermark, etc.) derived
        // by replaying the system session's degraded/restored events. Backs `correx health`.
        get("/health/checks") {
            call.respond(healthInspection.inspect())
        }

        // Per-model tool-call reliability across the whole event log (valid vs. failed tool calls
        // per provider). Measurement groundwork for capability-aware routing of tool-heavy stages.
        get("/metrics/tool-reliability") {
            call.respond(toolReliability.inspect())
        }

        webSocket("/stream") {
            globalStreamHandler.handle(this)
        }

        sessionRoutes(module)
        workflowRoutes(module)
        providerRoutes(module)
        taskRoutes(module)
    }
}
