package gaf3.core.gateway.filter.factory

import org.slf4j.LoggerFactory
import org.springframework.cloud.gateway.filter.GatewayFilter
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory
import org.springframework.core.style.ToStringCreator
import org.springframework.validation.annotation.Validated
import java.util.regex.Pattern
import javax.validation.constraints.NotEmpty

/**
 * @author dyg
 */
class HostToTenantGatewayFilterFactory : AbstractGatewayFilterFactory<HostToTenantGatewayFilterFactory.Config>(Config::class.java) {

    override fun shortcutFieldOrder(): List<String> {
        return arrayListOf(PATTERN_KEY)
    }

    override fun apply(config: Config): GatewayFilter {
        return GatewayFilter { exchange, chain ->
            // 提取Host
            val host = exchange.request.headers.getFirst("Host")
            //			host = exchange.getRequest().getHeaders().getFirst("X-Forwarded-Host");
            //			if(StringUtil.isNullOrEmpty(host))
            //				host = exchange.getRequest().getHeaders().getFirst("Host");

            val p = Pattern.compile(config.pattern!!)
            val m = p.matcher(host!!)
            if (m.matches()) {
                val tenant = m.group(1)
                val request = exchange.request.mutate()
                        .headers { httpHeaders ->
                            if (tenant != null)
                                httpHeaders[HEADER_TENANT] = tenant
                        }.build()
                log.debug("Set X-Tenant use Host: {}", tenant)
                return@GatewayFilter chain.filter(exchange.mutate().request(request).build())
            }
            chain.filter(exchange.mutate().build())
        }
    }

    @Validated
    class Config {
        @NotEmpty
        var pattern: String? = null

        override fun toString(): String {
            return ToStringCreator(this)
                    .append("pattern", pattern)
                    .toString()
        }
    }

    companion object {

        internal val log = LoggerFactory.getLogger(HostToTenantGatewayFilterFactory::class.java)

        const val HEADER_TENANT = "X-Tenant"
        const val PATTERN_KEY = "pattern"
    }
}
