/**
 * Copyright 2008-2020. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */

package com.crunii.micro.gateway.filter.web;

import com.crunii.micro.gateway.GatewayConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
 * @author 田平 create 2023-02-14 02:10:51
 * <pre>
 *     优先级必须低于XForwardedHeadersFilter
 * </pre>
 */
@Component
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnProperty(value = "spring.cloud.gateway.enablePrefix", havingValue = "true")
public class ApiPrefixFilter implements WebFilter {

	@Value("${spring.cloud.gateway.prefix:/api}")
	private String prefix;

	@Value("${spring.application.name}")
	private String appName;

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		String path = request.getURI().getRawPath();
		//设置真实的请求路径
		exchange.getAttributes().put(GatewayConstants.REAL_PATH, path);
		if (path.startsWith(prefix)) {
			//prefix开头的url自动截取前缀
			String newPath = path.replaceFirst(prefix, "");
			ServerHttpRequest newReq = request.mutate().path(newPath).build();
			return chain.filter(exchange.mutate().request(newReq).build());
		} else if (path.startsWith("/" + appName)) {
			//默认应用名称开头的url为网关本身的url不需要截取
			return chain.filter(exchange);
		} else {
			//非prefix开通的url直接返回错误网关
			ServerHttpResponse response = exchange.getResponse();
			response.setStatusCode(HttpStatus.BAD_GATEWAY);
			DataBuffer wrap = response.bufferFactory().wrap(HttpStatus.BAD_GATEWAY.getReasonPhrase().getBytes());
			return response.writeWith(Mono.just(wrap));
		}
	}

}
