package cclotus.weixin.api.feign

import cclotus.weixin.util.WeixinError
import com.alibaba.fastjson2.JSON
import com.alibaba.fastjson2.JSONValidator
import feign.FeignException
import feign.Response
import feign.codec.ErrorDecoder
import org.slf4j.LoggerFactory
import org.springframework.http.MediaType
import org.springframework.util.StreamUtils
import java.nio.charset.Charset
import kotlin.math.min

class WxErrorDecoder : ErrorDecoder{
    private val log = LoggerFactory.getLogger(WxErrorDecoder::class.java)

    override fun decode(methodKey: String, response: Response): Exception {
        val data = runCatching {
            response.body().asInputStream().use {
                StreamUtils.copyToString(it, Charset.defaultCharset())
            }
        }.getOrNull() ?: ""
        val isJson = response.headers()["content-type"]
                ?.stream()?.map { s -> MediaType.parseMediaType(s) }
                ?.anyMatch { c -> c.isCompatibleWith(MediaType.APPLICATION_JSON)}

        log.warn("HTTP Status {} - {}", response.status(), data.substring(0, min(100, data.length)))
        if(log.isTraceEnabled && data.length > 100) {
            log.trace(data)
        }
        var exception = FeignException.errorStatus(methodKey, response) as Exception
        if(response.status() == 400 && isJson == true && JSONValidator.from(data).validate()) {
            // 处理Http 400错误
            val res = JSON.parseObject(data)
            exception = if (!res.containsKey("errcode")) {
                WeixinError(WeixinError.ERR_BADPARAM, "请求参数错误")
            } else {
                WeixinError(
                    res.getInteger("errcode"),
                    res.getString("errmsg"),
                    res.getString("details")
                )
            }
        }
        return exception
    }
}