//package com.chushang.gateway.filter;
//
//import cn.hutool.json.JSONObject;
//import cn.hutool.json.JSONUtil;
//import com.chushang.common.core.web.Result;
//import lombok.extern.slf4j.Slf4j;
//import org.reactivestreams.Publisher;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
//import org.springframework.cloud.gateway.support.BodyInserterContext;
//import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.Ordered;
//import org.springframework.core.io.buffer.DataBuffer;
//import org.springframework.core.io.buffer.DataBufferUtils;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.HttpStatus;
//import org.springframework.http.server.reactive.ServerHttpResponse;
//import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
//import org.springframework.web.reactive.function.BodyInserter;
//import org.springframework.web.reactive.function.BodyInserters;
//import org.springframework.web.reactive.function.client.ClientResponse;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Flux;
//import reactor.core.publisher.Mono;
//
//@Slf4j
//@Configuration
//public class SanyiResponseGlobalFilter implements GlobalFilter, Ordered {
//
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        ServerHttpResponse originalResponse = exchange.getResponse();
//        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
//            @Override
//            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
//                String originalResponseContentType = exchange.getAttribute(ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
//                HttpHeaders httpHeaders = new HttpHeaders();
//                // explicitly add it in this way instead of
//                // 'httpHeaders.setContentType(originalResponseContentType)'
//                // this will prevent exception in case of using non-standard media
//                // types like "Content-Type: image"
//                httpHeaders.add(HttpHeaders.CONTENT_TYPE, originalResponseContentType);
//                ClientResponse clientResponse =
//                        prepareClientResponse(exchange.getResponse().getStatusCode(),body,httpHeaders);
//                Mono<String> modifiedBody = clientResponse.bodyToMono(String.class).flatMap(responseBody -> {
//                    JSONObject jsonObject = JSONUtil.parseObj(responseBody);
//                    log.info("error : {}", jsonObject);
//                    if (jsonObject.containsKey("timestamp")) {
//                        return Mono.just(JSONUtil.toJsonStr(Result.restResult(jsonObject.getStr("path"),
//                                jsonObject.getInt("status"),
//                                jsonObject.getStr("error"))));
//                    }
//                    return Mono.just(responseBody);
//                });
//                BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
//                HttpHeaders headers = new HttpHeaders();
//                headers.putAll(exchange.getResponse().getHeaders());
//                headers.remove(HttpHeaders.CONTENT_LENGTH);
//                CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
//                return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
//                    Mono<DataBuffer> messageBody = DataBufferUtils.join(outputMessage.getBody());
//                    if (!headers.containsKey(HttpHeaders.TRANSFER_ENCODING)
//                            || headers.containsKey(HttpHeaders.CONTENT_LENGTH)) {
//                        messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount()));
//                    }
//                    // TODO: fail if isStreamingMediaType?
//                    return getDelegate().writeWith(messageBody);
//                }));
//            }
//        };
//        // replace response with decorator
//        return chain.filter(exchange.mutate().response(decoratedResponse).build());
//    }
//
//    @Override
//    public int getOrder() {
//        // -1 is response write filter, must be called before that
//        return -2;
//    }
//
//    private ClientResponse prepareClientResponse(HttpStatus httpStatus, Publisher<? extends DataBuffer> body, HttpHeaders httpHeaders) {
//        ClientResponse.Builder builder;
//        builder = ClientResponse.create(httpStatus);
//        return builder.headers(headers -> headers.putAll(httpHeaders)).body(Flux.from(body)).build();
//    }
//}