package de.kif.backend

import com.fasterxml.jackson.databind.SerializationFeature
import de.kif.backend.route.*
import de.kif.backend.route.api.*
import de.kif.backend.util.pushService
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.*
import io.ktor.http.HttpStatusCode
import io.ktor.http.content.files
import io.ktor.http.content.static
import io.ktor.jackson.jackson
import io.ktor.response.respond
import io.ktor.routing.route
import io.ktor.routing.routing
import org.slf4j.event.Level
import java.nio.file.Paths

val prefix = Configuration.Server.prefix

fun Application.main() {
    install(DefaultHeaders)
    install(CallLogging) {
        if (Configuration.Server.debug) {
            level = Level.INFO
        }
    }
    install(ConditionalHeaders)
    install(Compression)
    install(DataConversion)
    install(AutoHeadResponse)

    install(StatusPages) {
        exception<Throwable> {
            it.printStackTrace()
            call.respond(HttpStatusCode.InternalServerError)
        }
        statusFile(HttpStatusCode.NotFound, HttpStatusCode.InternalServerError, filePattern = "error#.html")
    }

    install(ContentNegotiation) {
        jackson {
            enable(SerializationFeature.INDENT_OUTPUT)
        }
    }

    security()

    routing {

        route(prefix) {
            static("/static") {
                files(Configuration.Path.webPath.toFile())
            }

            static("/images") {
                files(Configuration.Path.uploadsPath.toFile())
            }

            val srcFile = Paths.get("src")?.toFile()
            if (srcFile != null && srcFile.exists() && srcFile.isDirectory) {
                static("/src") {
                    files("src")
                }
            }

            // UI routes
            overview()
            calendar()
            login()
            account()

            board()
            wall()

            workGroup()
            track()
            room()
            user()

            // RESTful routes
            authenticateApi()

            roomApi()
            scheduleApi()
            trackApi()
            userApi()
            workGroupApi()
            constraintsApi()
            postApi()
            announcementApi()

            // Web socket push notifications
            pushService()
        }
    }
}
