package api;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.param.AppTokenReq;
import com.sunyard.chsm.param.AppTokenResp;
import com.sunyard.chsm.utils.CodecUtils;
import com.sunyard.chsm.utils.JsonUtils;
import com.sunyard.chsm.utils.gm.BCSM3Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Optional;

/**
 * @author liulu
 * @since 2024/12/17
 */
@Slf4j
public abstract class BaseTest {

    protected static final String keyTemplate = "sym-sm4-001";
    protected static final String asymKeyTemplate = "asym-sm2-001";
    protected static final String ak = "216205d408130d83d13c5072305b8b65";
    protected static final String sk = "ae64515d1d5adec2cc6ae8726d0c1bbc";
    protected static final String server = "http://172.16.18.46:8900";
    protected static final RestTemplate restTemplate;
    protected static final String token;

    static {
        AppTokenReq req = new AppTokenReq();
        req.setAppKey(ak);
        req.setTimestamp(System.currentTimeMillis());
        byte[] hmac = BCSM3Utils.hmac(sk.getBytes(), (ak + req.getTimestamp() + sk).getBytes());
        req.setHmac(CodecUtils.encodeBase64(hmac));

        RequestEntity<byte[]> request = RequestEntity.post(server + "/appUser/getAppToken")
                .contentType(MediaType.APPLICATION_JSON)
                .body(JsonUtils.toJsonBytes(req));
        ResponseEntity<String> response = new RestTemplate().exchange(request, String.class);
        try {
            R<AppTokenResp> r = JsonUtils.objectMapper()
                    .readValue(response.getBody(), new TypeReference<R<AppTokenResp>>() {
                    });
            token = r.getResult().getToken();
            restTemplate = new RestTemplateBuilder()
                    .rootUri(server)
                    .defaultHeader("Authorization", "Bearer " + token)
                    .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
                    .build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    protected static <T> T execute(String url, Object req, Class<T> tClass) {
        try {
            byte[] res = restTemplate.postForObject(url, JsonUtils.toJsonBytes(req), byte[].class);

            JsonNode jsonNode = JsonUtils.objectMapper()
                    .readTree(res);
            boolean success = jsonNode.get("success").asBoolean();
            String message = Optional.ofNullable(jsonNode.get("message")).map(JsonNode::asText).orElse("");
            if (!success) {
                log.warn(message);
                return null;
            }
            JsonNode result = jsonNode.get("result");
            if (result == null) {
                return null;
            }
            JsonParser returnJsonParser = JsonUtils.objectMapper().treeAsTokens(result);
            return JsonUtils.objectMapper().readValue(returnJsonParser, tClass);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
