package {{packageName}}

// Use this file to hold package-level internal functions that return receiver object passed to the `install` method.
import io.ktor.auth.OAuthServerSettings
import io.ktor.features.*
import io.ktor.http.*
import io.ktor.util.KtorExperimentalAPI
import java.time.Duration
import java.util.concurrent.Executors

import {{packageName}}.settings

{{#featureCORS}}
/**
 * Application block for [CORS] configuration.
 *
 * This file may be excluded in .openapi-generator-ignore,
 * and application specific configuration can be applied in this function.
 *
 * See http://ktor.io/features/cors.html
 */
internal fun ApplicationCORSConfiguration(): CORS.Configuration.() -> Unit {
    return {
        // method(HttpMethod.Options)
        // header(HttpHeaders.XForwardedProto)
        // anyHost()
        // host("my-host")
        // host("my-host:80")
        // host("my-host", subDomains = listOf("www"))
        // host("my-host", schemes = listOf("http", "https"))
        // allowCredentials = true
        // maxAge = Duration.ofDays(1)
    }
}
{{/featureCORS}}

{{#featureHSTS}}
/**
 * Application block for [HSTS] configuration.
 *
 * This file may be excluded in .openapi-generator-ignore,
 * and application specific configuration can be applied in this function.
 *
 * See http://ktor.io/features/hsts.html
 */
internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit {
    return {
        maxAge = Duration.ofDays(365)
        includeSubDomains = true
        preload = false

        // You may also apply any custom directives supported by specific user-agent. For example:
        // customDirectives.put("redirectHttpToHttps", "false")
    }
}
{{/featureHSTS}}

{{#featureCompression}}
/**
 * Application block for [Compression] configuration.
 *
 * This file may be excluded in .openapi-generator-ignore,
 * and application specific configuration can be applied in this function.
 *
 * See http://ktor.io/features/compression.html
 */
internal fun ApplicationCompressionConfiguration(): Compression.Configuration.() -> Unit {
    return {
        gzip {
            priority = 1.0
        }
        deflate {
            priority = 10.0
            minimumSize(1024) // condition
        }
    }
}
{{/featureCompression}}

// Defines authentication mechanisms used throughout the application.
@KtorExperimentalAPI
val ApplicationAuthProviders: Map<String, OAuthServerSettings> = listOf<OAuthServerSettings>(
{{#authMethods}}
    {{#isOAuth}}
        OAuthServerSettings.OAuth2ServerSettings(
            name = "{{name}}",
            authorizeUrl = "{{authorizationUrl}}",
            accessTokenUrl = "{{tokenUrl}}",
            requestMethod = HttpMethod.Get,
            {{! TODO: flow, doesn't seem to be supported yet by ktor }}
            clientId = settings.property("auth.oauth.{{name}}.clientId").getString(),
            clientSecret = settings.property("auth.oauth.{{name}}.clientSecret").getString(),
            defaultScopes = listOf({{#scopes}}"{{scope}}"{{#hasMore}}, {{/hasMore}}{{/scopes}})
        ){{#hasMore}},{{/hasMore}}
    {{/isOAuth}}
{{/authMethods}}
//        OAuthServerSettings.OAuth2ServerSettings(
//                name = "facebook",
//                authorizeUrl = "https://graph.facebook.com/oauth/authorize",
//                accessTokenUrl = "https://graph.facebook.com/oauth/access_token",
//                requestMethod = HttpMethod.Post,
//
//                clientId = "settings.property("auth.oauth.facebook.clientId").getString()",
//                clientSecret = "settings.property("auth.oauth.facebook.clientSecret").getString()",
//                defaultScopes = listOf("public_profile")
//        )
).associateBy { it.name }

// Provides an application-level fixed thread pool on which to execute coroutines (mainly)
internal val ApplicationExecutors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4)
