package space.nstart.pcp_gateway_service.config

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.web.server.SecurityWebFilterChain

/**
 * Политика edge. Две взаимоисключающие цепочки, переключаемые флагом
 * `gateway.security.jwt-enabled` (завязан на режим входа фронта):
 *  - выключено (anonymous, текущий дефолт) — пропускаем всё: поведение как при прямых вызовах;
 *  - включено (закрытый контур new-start-id) — валидируем Bearer JWT один раз здесь, дальше
 *    gateway по умолчанию пробрасывает заголовок Authorization вниз к сервисам.
 *
 * Когда JWT выключен, `spring.security.oauth2.resourceserver.jwt.issuer-uri` не задаётся,
 * поэтому JwtDecoder не создаётся и старт не падает из-за пустого issuer.
 */
@Configuration
@EnableWebFluxSecurity
class SecurityConfig {

    @Bean
    @ConditionalOnProperty(prefix = "gateway.security", name = ["jwt-enabled"], havingValue = "true")
    fun securedChain(http: ServerHttpSecurity): SecurityWebFilterChain =
        http
            .csrf { it.disable() }
            .authorizeExchange { exchanges ->
                exchanges
                    .pathMatchers(HttpMethod.OPTIONS).permitAll()
                    .pathMatchers("/healthz", "/actuator/**").permitAll()
                    .anyExchange().authenticated()
            }
            .oauth2ResourceServer { it.jwt {} }
            .build()

    @Bean
    @ConditionalOnProperty(
        prefix = "gateway.security",
        name = ["jwt-enabled"],
        havingValue = "false",
        matchIfMissing = true,
    )
    fun openChain(http: ServerHttpSecurity): SecurityWebFilterChain =
        http
            .csrf { it.disable() }
            .authorizeExchange { it.anyExchange().permitAll() }
            .build()
}
