package org.jeecg.modules.adweb.common.util;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.codec.binary.Base64;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * {@link RestTemplate}初始化及工厂类
 *
 * <p>普通文本类型HTTP请求，请使用{@link org.jeecg.common.util.RestUtil}
 *
 * @author wfansh
 */
@Slf4j
public class RestTemplateUtil {

    /**
     * @return 通过Bearer token认证的 {@link RestTemplate}
     */
    public static RestTemplate getRestTemplate(
            int connectTimeoutSeconds, int readTimeoutSeconds, String bearerToken) {
        return getRestTemplate(
                connectTimeoutSeconds,
                readTimeoutSeconds,
                Map.of(HttpHeaders.AUTHORIZATION, "Bearer " + bearerToken));
    }

    /**
     * @return 通过userName + password认证的 {@link RestTemplate}
     */
    public static RestTemplate getRestTemplate(
            int connectTimeoutSeconds, int readTimeoutSeconds, String userName, String password) {
        String auth = userName + ":" + password;
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));

        return getRestTemplate(
                connectTimeoutSeconds,
                readTimeoutSeconds,
                Map.of(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth)));
    }

    /** HTTP POST请求读取对象 */
    public static <T> T postForObject(
            RestTemplate restTemplate,
            String url,
            Object request,
            ParameterizedTypeReference<T> responseType)
            throws RestClientException {
        RequestEntity<?> requestEntity = RequestEntity.post(url).body(request);
        return restTemplate.exchange(requestEntity, responseType).getBody();
    }

    /** HTTP GET请求读取对象 */
    public static <T> T getForObject(
            RestTemplate restTemplate, String url, ParameterizedTypeReference<T> responseType)
            throws RestClientException {
        RequestEntity<?> requestEntity = RequestEntity.get(url).build();
        return restTemplate.exchange(requestEntity, responseType).getBody();
    }

    private static RestTemplate getRestTemplate(
            int connectTimeoutSeconds, int readTimeoutSeconds, Map<String, String> httpHeaders) {
        // 1. 请求超时
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(1000 * connectTimeoutSeconds);
        requestFactory.setReadTimeout(1000 * readTimeoutSeconds);

        RestTemplate restTemplate = new RestTemplate(requestFactory);

        // 2. HTTP请求头
        restTemplate
                .getInterceptors()
                .add(
                        ((request, body, execution) -> {
                            httpHeaders
                                    .entrySet()
                                    .forEach(
                                            entry ->
                                                    request.getHeaders()
                                                            .add(entry.getKey(), entry.getValue()));

                            return execution.execute(request, body);
                        }));

        return restTemplate;
    }
}
