/**
 * 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 java.net.URI;
import java.util.Date;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
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 com.crunii.micro.common.constants.CommonConstants;
import com.crunii.micro.common.exception.MicroException;
import com.crunii.micro.common.utils.DateUtil;

import reactor.core.publisher.Mono;

/**
 * @author GuoHF
 * @createTime 2020-11-20 15:58:44
 */
@Component
@Slf4j(topic = "requestInfo")
public class GatewayLogFilter implements WebFilter, Ordered {

	public static final String headerName = "ServiceSystem";
	public static final String headerValue = "MicroGateway";

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

		URI path = exchange.getRequest().getURI();
		String method = exchange.getRequest().getMethodValue();
		String token = exchange.getRequest().getHeaders().getFirst(CommonConstants.HEADER_TOKEN);
		Date begin = new Date();
		exchange.getAttributes().put("request_time", begin);
		ServerHttpResponse originalResponse = exchange.getResponse();
		HttpHeaders hds = originalResponse.getHeaders();
		hds.add(headerName, headerValue);
		log.info("call url:{} start used:{} s,method=[{}],token=[{}]", path, DateUtil.getUseSecond(begin), method, token);
		return chain.filter(exchange).doOnSuccess(s -> {
			log.info("call url:{} success used:{} s,method=[{}],token=[{}]", path, DateUtil.getUseSecond(begin), method, token);
		}).doOnError(e -> {
			log.info("call url:{} failure! used:{} s,method=[{}],token=[{}],error=[{}]", path, DateUtil.getUseSecond(begin), method, token,
					MicroException.getErrorMsg(e));
		});
	}

	@Override
	public int getOrder() {
		return Integer.MIN_VALUE;
	}

}
