package gaf3.core.cloud.web.reactive

import gaf3.core.cloud.web.GafSpaConfigure
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.web.server.ResponseStatusException
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono

class GafSpaWebFilter(val config: GafSpaConfigure) : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        if (config.enabled && config.indexPaths.isNotEmpty()) {
            config.indexPaths.forEach {
                if (exchange.request.uri.path == it || exchange.request.uri.path.startsWith("$it/") ) {
                    return chain.filter(exchange)
                            .onErrorResume(ResponseStatusException::class.java) { ex ->
                                if (ex.status == HttpStatus.NOT_FOUND) {
                                    log.debug("[404] {}", exchange.request.uri.path)
                                    return@onErrorResume chain.filter(buildIndex(it, exchange))
                                }
                                log.debug("!!!!! filter catch error: {} !!!!!", ex.message)
                                Mono.error(ex)
                            }
                }
            }
        }
        return chain.filter(exchange)
    }

    private fun buildIndex(prefix: String, exchange: ServerWebExchange): ServerWebExchange {
        return exchange.mutate().request(exchange.request.mutate().path("${prefix}/${config.indexFile}").build()).build()
    }

    companion object {
        internal val log = LoggerFactory.getLogger(GafSpaWebFilter::class.java)
    }
}