package com.cusc.nirvana.user.rnr.fp.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.cusc.nirvana.common.result.PageResult;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.rnr.fp.common.FpLogOutputJsonSerializeFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * Description: resttemplate封装
 * <br />
 * CreateDate 2021-11-01 16:46
 *
 * @author yuyi
 **/
public class RnrFpRestTemplateUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(RnrFpRestTemplateUtils.class);


    /**
     * Description: post请求Response泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> Response<T> postForResponse(RestTemplate restTemplate, String url, Object request,
                                                  Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForResponse url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(request), String.class, urlVariables);
        Response<T> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<T>>(cls) {
        }.getType());
        LOGGER.info("postForResponse url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求Response泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static Response postForResponse(RestTemplate restTemplate, String url, Object request,
                                           Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForResponse url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(request), String.class, urlVariables);
        Response result = JSON.parseObject(entity.getBody(), Response.class);
        LOGGER.info("postForResponse url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求Response泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static Response postOpenApiForResponse(RestTemplate restTemplate, String url, HttpEntity request,
                                                  Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postOpenApiForResponse url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, request, String.class, urlVariables);
        Response result = JSON.parseObject(entity.getBody(), Response.class);
        LOGGER.info("postOpenApiForResponse url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求Response<PageResult>泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> Response<PageResult<T>> postForResponsePageResult(RestTemplate restTemplate, String url,
                                                                        Object request,
                                                                        Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForResponsePageResult url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(request), String.class, urlVariables);
        Response<PageResult<T>> result = JSON.parseObject(entity.getBody(),
                new TypeReference<Response<PageResult<T>>>(cls) {
                }.getType());
        LOGGER.info("postForResponsePageResult url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求Response<List>泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> Response<List<T>> postForResponseList(RestTemplate restTemplate, String url, Object request,
                                                            Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForResponseList url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(request), String.class, urlVariables);
        Response<List<T>> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<List<T>>>(cls) {
        }.getType());
        LOGGER.info("postForResponseList url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> T postForObject(RestTemplate restTemplate, String url, Object request,
                                      Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForObject url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(request), String.class, urlVariables);
        LOGGER.info("postForObject url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(entity.getBody(), new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return JSON.parseObject(entity.getBody(), cls);
    }

    /**
     * Description: post请求泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> T postOpenApiForObject(RestTemplate restTemplate, String url, HttpEntity request,
                                             Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postOpenApiForObject url: {},request: {}", url,
                JSON.toJSONString(request, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, request, String.class, urlVariables);
        LOGGER.info("postOpenApiForObject url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(entity.getBody(), new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return JSON.parseObject(entity.getBody(), cls);
    }

    /**
     * Description: post请求泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> T postForObject(RestTemplate restTemplate, String url, HttpEntity<?> requestEntity,
                                      Class<T> cls, Object... urlVariables) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("postForObject url: {},request: {}", url,
                JSON.toJSONString(requestEntity, new FpLogOutputJsonSerializeFilter()));
        ResponseEntity<String> entity =
                restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class, urlVariables);
        T result = JSON.parseObject(entity.getBody(), cls);
        LOGGER.info("postForObject url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: get 请求响应泛型对象
     * <br />
     * CreateDate 2022-05-13 18:41:15
     *
     * @author yuyi
     **/
    public static <T> T getForObject(RestTemplate restTemplate, String url, Class<T> cls) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("getForObject url: {}", url);
        ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
        T result = JSON.parseObject(entity.getBody(), cls);
        LOGGER.info("getForObject url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Description: post请求Response泛型
     * <br />
     * CreateDate 2021-11-01 16:53:25
     *
     * @author yuyi
     **/
    public static <T> Response<T> getForResponse(RestTemplate restTemplate, String url, Class<T> cls) {
        long startTime = System.currentTimeMillis();
        LOGGER.info("getForResponse url: {}", url);
        ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
        Response<T> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<T>>(cls) {
        }.getType());
        LOGGER.info("getForResponse url: {},response: {},cost: {} ms", url,
                JSON.toJSONString(result, new FpLogOutputJsonSerializeFilter()),
                System.currentTimeMillis() - startTime);
        return result;
    }
}
