package weaver.interfaces.htsc.util;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.cloudstore.dev.api.util.Util_DataCache;
import com.engine.core.exception.ECException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import weaver.general.Util;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.rsa.security.RSA;

import java.util.Map;


/**
 * @Author weaver_cl
 * @Date 2020/8/7
 * @Version V1.0
 **/
@Slf4j
public class TokenUtil {
    /**
     * redis key
     */
    private static final String REDIS_PIX = "weaver.api.";
    private static final String CACHE_SPK_KEY = REDIS_PIX + "spk";
    private static final String CACHE_SECRET_KEY = REDIS_PIX + "secret";
    private static final String CACHE_TOKEN_KEY = REDIS_PIX + "token";


    public static final String API_ADDRESS = "api.address";

    private static final PropBean propBean=new PropBean();

    /**
     * 注册
     */
    public static final String ECOLOGY_API_REGIST = "/api/ec/dev/auth/regist";

    /**
     * 申请token
     */
    public static final String ECOLOGY_API_APPLY_TOKEN = "/api/ec/dev/auth/applytoken";


    public static String post(String env, String api, Map<String,Object> formMap, String appId){
        final EcologyAuthDTO ecologyAuthDTO = getToken(env, appId);
        log.info("post 请求参数:[{}]",JSON.toJSONString(formMap));
        RSA rsa = new RSA();
        String encryptUserid =  rsa.encrypt(null, getApiUserId(), null, "utf-8", ecologyAuthDTO.getSpk(), false);
        log.info("加密后userid：[{}]", encryptUserid);
        final String url = getAddressByEnv(env) + api;
        log.info("post url:[{}]", url);
        //调用ECOLOGY系统接口
        String data = HttpRequest.post(url)
                .header("appid",appId)
                .header("Content-Type", "application/json")
                .header("token", ecologyAuthDTO.getToken())
                .header("userid",encryptUserid)
                .form(formMap)
                .execute().body();
        log.info("post请求返回:[{}]",data);
        return data;
    }

    public static String post(String env, String api, String jsonParam, String appId){
        final EcologyAuthDTO ecologyAuthDTO = getToken(env, appId);
        log.info("post 请求参数:[{}]",jsonParam);
        RSA rsa = new RSA();
        String encryptUserid =  rsa.encrypt(null, getApiUserId(), null, "utf-8", ecologyAuthDTO.getSpk(), false);
        log.info("加密后userid：[{}]", encryptUserid);
        final String url = getAddressByEnv(env) + api;
        log.info("post url:[{}]", url);
        //调用ECOLOGY系统接口
        String data = HttpRequest.post(url)
                .header("appid",appId)
                .header("Content-Type", "application/json")
                .header("token", ecologyAuthDTO.getToken())
                .header("userid",encryptUserid)
                .body(jsonParam)
                .execute().body();
        log.info("post请求返回:[{}]",data);
        return data;
    }
    public static String get(String env,String api,String jsonParam,String appId){
        final EcologyAuthDTO ecologyAuthDTO = getToken(env, appId);
        RSA rsa = new RSA();
        String encryptUserid =  rsa.encrypt(null, getApiUserId(), null, "utf-8", ecologyAuthDTO.getSpk(), false);
        log.info("get 请求参数:[{}]",jsonParam);
        log.info("加密后userid：[{}]", encryptUserid);
        final String url = getAddressByEnv(env) + api;
        log.info("post url:[{}]", url);
        //调用ECOLOGY系统接口
        String data = HttpRequest.get(url)
                .header("appid",appId)
                .header("Content-Type", "application/json")
                .header("token",ecologyAuthDTO.getToken())
                .header("userid",encryptUserid)
                .body(jsonParam)
                .execute().body();
        log.info("get请求返回：[{}]",data);
        return data;
    }


    public static String get(String env,String api,Map<String,Object> formMap,String appId){
        final EcologyAuthDTO ecologyAuthDTO = getToken(env, appId);
        RSA rsa = new RSA();
        String encryptUserid =  rsa.encrypt(null, getApiUserId(), null, "utf-8", ecologyAuthDTO.getSpk(), false);
        log.info("get 请求参数:[{}]",JSON.toJSONString(formMap));
        log.info("加密后userid：[{}]", encryptUserid);
        final String url = getAddressByEnv(env) + api;
        log.info("post url:[{}]", url);
        //调用ECOLOGY系统接口
        String data = HttpRequest.get(url)
                .header("appid",appId)
                .header("Content-Type", "application/json")
                .header("token",ecologyAuthDTO.getToken())
                .header("userid",encryptUserid)
                .form(formMap)
                .execute().body();
        log.info("get请求返回：[{}]",data);
        return data;
    }

    /**
     * 根据环境参数和appid获取token
     * @param env
     * @param appId
     * @return
     */
    public static EcologyAuthDTO getToken(String env,String appId) {
        // 从缓存获取token
        String token = getCache(env,CACHE_TOKEN_KEY);
        String spk = getCache(env,CACHE_SPK_KEY);
        String secrit = getCache(env,CACHE_SECRET_KEY);

        if (StringUtils.isNotEmpty(token)&&StringUtils.isNotBlank(spk)&&StringUtils.isNotBlank(secrit)) {
            log.info("从缓存中获取");
            final EcologyAuthDTO ecologyAuthDTO = new EcologyAuthDTO();
            ecologyAuthDTO.setToken(token);
            ecologyAuthDTO.setSpk(spk);
            ecologyAuthDTO.setSecrit(secrit);
            ecologyAuthDTO.setStatus(true);
            return ecologyAuthDTO;
        }

        // 重新注册
        if (StringUtils.isEmpty(spk) || StringUtils.isEmpty(secrit)) {
            log.info("spk 或 secrit 为空");
            EcologyAuthDTO ecologyAuthDTO= register(env, appId);
            if (ecologyAuthDTO.getStatus()) {
                log.info("注册成功");
                setCache(getKeyWithEnv(env,CACHE_SPK_KEY), ecologyAuthDTO.getSpk());
                setCache(getKeyWithEnv(env,CACHE_SECRET_KEY), ecologyAuthDTO.getSecrit());
                spk=ecologyAuthDTO.getSpk();
                secrit=ecologyAuthDTO.getSecrit();
            } else {
                log.error("注册失败:[{}]", ecologyAuthDTO.getMsg());
                throw new ECException("注册失败:" + ecologyAuthDTO.getMsg());
            }
        }

        // 申请token
        RSA rsa = new RSA();
        log.info("secrit:[{}],spk:[{}]",secrit,spk);
        String encryptSecret = rsa.encrypt(null, secrit, null, "utf-8", spk, false);
        log.info("加密后encryptSecret：[{}]", encryptSecret);

        String res = HttpRequest.post(getAddressByEnv(env) + ECOLOGY_API_APPLY_TOKEN).header("appid", appId).header("secret", encryptSecret).execute().body();

        log.info("get response apply token {}", res);

        final EcologyAuthDTO tokenDTO = JSON.parseObject(res, EcologyAuthDTO.class);
        if (tokenDTO.getStatus()) {
            setExCache(getKeyWithEnv(env,CACHE_TOKEN_KEY),getExpireTime(),tokenDTO.getToken());
            tokenDTO.setSpk(spk);
            tokenDTO.setSecrit(secrit);
        } else {
            log.error("申请token失败:[{}]", tokenDTO.getMsg());
            throw new ECException("申请token失败:" + tokenDTO.getMsg());
        }
        return tokenDTO;

    }



    private static synchronized EcologyAuthDTO register(String env,String appid) {
        // double check
        String spk = getCache(env,CACHE_SPK_KEY);
        String secret = getCache(env,CACHE_SECRET_KEY);
        if (StringUtils.isNotEmpty(spk) && StringUtils.isNotEmpty(secret)) {
            log.info("spk is not empty");
            final EcologyAuthDTO ecologyAuthDTO = new EcologyAuthDTO();
            ecologyAuthDTO.setStatus(true);
            ecologyAuthDTO.setSpk(spk);
            ecologyAuthDTO.setSecrit(secret);
            return ecologyAuthDTO;
        }
        String publicKey = RSA.getRSA_PUB();
        // 注册
        final String url = getAddressByEnv(env) + ECOLOGY_API_REGIST;
        log.info("url:[{}]",url);
        String res = HttpRequest.post(url).header("appid", appid).header("cpk", publicKey).execute().body();
        log.info("get response register {}", res);

        return JSON.parseObject(res, EcologyAuthDTO.class);

    }
    /**
     * token过期时间
     * @return
     */
    private static int getExpireTime(){
        try {
            return Integer.parseInt(propBean.getPropName("token.expire.time"));
        }catch (Exception e){
            log.error("获取token过期时间失败",e);
        }
        return 1800;

    }

    private static String getKeyWithEnv(String env,String key){
        return env+"."+key;
    }

    private static String getAddressByEnv(String env){
        return propBean.getPropName(getKeyWithEnv(env, API_ADDRESS));
    }

    private static String getCache(String env, String key){
        return Util.null2String(Util_DataCache.getObjVal(getKeyWithEnv(env, key)));
    }

    private static void  setCache(String key,String val){
        Util_DataCache.setObjVal(key,val);
    }

    private static void setExCache(String key,int ex,String value){
        Util_DataCache.setObjVal(key,value,ex);
    }

    /**
     * 调用apid用户
     * @return
     */
    private static String getApiUserId(){
        return propBean.getPropName("weaver.api.user");
    }



}
