package com.tmerclub.cloud.systemtest.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.util.Json;

import java.util.List;
import java.util.Objects;

/**
 * @author lanhai
 */
public class HttpUtil {

    public static void get(String url, UrlEnum urlEnum) {
        HttpResponse response = doGet(url, urlEnum);
        CheckUtil.check(response);
    }

    public static <T> T get(String url, Class<T> clazz, UrlEnum urlEnum) {
        HttpResponse response = doGet(url, urlEnum);
        return CheckUtil.checkAndGetObject(response,clazz);
    }

    public static <T> String gets(String url, UrlEnum urlEnum) {
        HttpResponse response = doGet(url, urlEnum);
        return CheckUtil.checkAndGetObjects(response);
    }


    public static void post(String url, Object obj, UrlEnum urlEnum) {
        HttpResponse response = doPost(url, obj, urlEnum);
        CheckUtil.check(response);
    }
    public static <T> T post(String url, Object obj, UrlEnum urlEnum ,Class<T> clazz) {
        HttpResponse response = doPost(url, obj, urlEnum);
        return CheckUtil.checkAndGetObject(response,clazz);
    }


    public static void put(String url, Object obj, UrlEnum urlEnum) {
        HttpResponse response = doPut(url, obj, urlEnum);
        CheckUtil.check(response);
    }

    public static void put(String url, UrlEnum urlEnum) {
        HttpResponse response = doPut(url,null, urlEnum);
        CheckUtil.check(response);
    }
    public static <T> ServerResponseEntity<T> puts(String url, Object obj, UrlEnum urlEnum) {
        HttpResponse response = doPut(url, obj, urlEnum);
        String body = response.body();
        TypeReference<ServerResponseEntity<T>> typeReference = new TypeReference<ServerResponseEntity<T>>(ServerResponseEntity.class) {};
        ServerResponseEntity<T> serverResponseEntity = JSON.parseObject(body, typeReference);
        return serverResponseEntity;
    }

    public static <T> List<T> putResultArray(String url, Object obj, Class<T[]> clazz, UrlEnum urlEnum) {
        HttpResponse response = doPut(url, obj, urlEnum);
        return CheckUtil.checkAndGetArray(response,clazz);
    }


    public static void delete(String url, UrlEnum urlEnum) {
        HttpResponse response = doDelete(url, urlEnum);
        CheckUtil.check(response);
    }

    public static void delete(String url, Object obj, UrlEnum urlEnum) {
        HttpResponse response = doDelete(url, obj, urlEnum);
        CheckUtil.check(response);
    }

    public static <T> T delete(String url, Class<T> clazz, UrlEnum urlEnum) {
        HttpResponse response = doDelete(url, urlEnum);
        return CheckUtil.checkAndGetObject(response,clazz);
    }

    public static <T> List<T> deleteResultArray(String url, Class<T[]> clazz, UrlEnum urlEnum) {
        HttpResponse response = doDelete(url, urlEnum);
        return CheckUtil.checkAndGetArray(response,clazz);
    }

    private static HttpResponse doGet(String url, UrlEnum urlEnum) {
        HttpRequest postRequest = HttpRequest.get(url);
        setHeader(postRequest, urlEnum);
        return postRequest.execute();
    }

    private static HttpResponse doPost(String url, Object obj, UrlEnum urlEnum) {
        HttpRequest postRequest = HttpRequest.post(url);
        setHeader(postRequest, urlEnum);
        // 如果是String类型，直接发送， 通过json转换成String发送会多出双引号
        if (obj instanceof String) {
            return postRequest.body(obj.toString()).execute();
        }
        return postRequest
                .body(JSON.toJSONString(obj))
                .execute();
    }

    /**
     * 需要权限校验的put请求
     * @param url
     * @param obj
     * @param urlEnum com.yami.shop.systemtest.util.UrlEnum
     * @return
     */
    private static HttpResponse doPut(String url, Object obj, UrlEnum urlEnum) {
        HttpRequest postRequest = HttpRequest.put(url);
        setHeader(postRequest, urlEnum);
        // 如果是String类型，直接发送， 通过json转换成String发送会多出双引号
        if (obj instanceof String) {
            return postRequest.body(obj.toString()).execute();
        }
        return postRequest
                .body(JSON.toJSONString(obj))
                .execute();
    }

    private static HttpResponse doDelete(String url, UrlEnum urlEnum) {
        HttpRequest postRequest = HttpRequest.delete(url);
        setHeader(postRequest, urlEnum);
        return postRequest.execute();
    }

    private static HttpResponse doDelete(String url, Object obj, UrlEnum urlEnum) {
        HttpRequest postRequest = HttpRequest.delete(url);
        setHeader(postRequest, urlEnum);
        return postRequest
                .body(Json.toJsonString(obj))
                .contentType("application/json")
                .execute();
    }

    private static void setHeader(HttpRequest httpRequest, UrlEnum urlEnum) {
        httpRequest.header("content-type", "application/json");
        httpRequest.header("Accept", "*/*");
        // 自定义token
        if (Objects.nonNull(urlEnum)) {
            httpRequest.header("authorization", urlEnum.token());
        }
    }
}
