package com.zcxk.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Component
public class AuthGatewayFilter implements GatewayFilter, Ordered {
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    public static final String tokenHead = "Bearer ";

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

        List<String> list =  exchange.getRequest().getHeaders().get("Authorization");
        String token = null;
        if(list != null && list.size() > 0){
            String authHeader = list.get(0);
            token = authHeader.substring(tokenHead.length());
        }else {
            MultiValueMap<String,String> map = exchange.getRequest().getQueryParams();
            String rmcpToken = getParam(map,"token");
            if (rmcpToken != null) {
                token = rmcpToken;
            }
        }

        String iotTokenKey = "iotToken:" + token;
        String iotToken = redisTemplate.opsForValue().get(iotTokenKey);
        if (iotToken != null) {
            redisTemplate.expire(iotTokenKey,30*60, TimeUnit.SECONDS);
            Consumer<HttpHeaders> httpHeaders = httpHeader -> {
                httpHeader.set("Authorization", "Bearer " + iotToken);
            };
            ServerHttpRequest newRequest = exchange.getRequest().mutate().headers(httpHeaders).build();
            return chain.filter(exchange.mutate().request(newRequest).build());
        }else {
            return chain.filter(exchange);
        }


    }


    @Override
    public int getOrder() {
        return 10;
    }

    private String getParam(MultiValueMap<String, String> map, String param) {
        if (map != null) {
            List<String> list = map.get(param);
            if (list != null && list.size() > 0) {
                return list.get(0);
            }
        }
        return null;
    }
}
