package com.bcxin.identify.startup;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrSpliter;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bcxin.identify.components.HotCacheProvider;
import com.bcxin.identify.util.PublicConst;
import com.bcxin.identify.util.Result;
import com.bcxin.identify.util.codes.CommonConst;
import com.bcxin.identify.util.codes.HuaweiMeetConst;
import com.bcxin.identify.util.codes.New_TLSSigAPIv2;
import com.bcxin.identify.util.common.StringUtil;
import com.bcxin.identify.util.getui.GTErrorEnum;
import com.bcxin.identify.util.getui.GeTuiUtil;
import com.bcxin.identify.util.huawei.HttpBuildUtil;
import com.bcxin.identify.util.huawei.RestRequest;
import com.bcxin.identify.util.huawei.RestResponse;
import com.bcxin.identify.util.sys.ConfigUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <b> 缓存配置加载 </b>
 * @author ZXF
 * @create 2021/01/28 0028 17:25
 * @version
 * @注意事项 </b>
 */
@Service
public class CacheService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HotCacheProvider hotCacheProvider;

    /**
     * 日志对象
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());

    private static List<String> TOKEN_KEY_LIST = Lists.newArrayList();

    private static String CURRENT_TOKEN = null;

    private static List<String> TOKEN_KEY_LIST_CHANNEL = Lists.newArrayList();

    private static String CURRENT_TOKEN_CHANNEL = null;

    private static List<String> ORC_TOKEN_KEY_LIST = Lists.newArrayList();

    private static String ORC_CURRENT_TOKEN = null;

    private static List<String> KT_TOKEN_KEY_LIST = Lists.newArrayList();

    private static String KT_CURRENT_TOKEN = null;


    /**
     * <b> 获取百度V3access_token </b>
     *
     * @author ZXF
     * @create 2020/10/27 0027 16:50
     * @version
     * @注意事项 </b>
     */
    public String getBaiduV3AccessToken(Object appointChannel) {
        if (appointChannel != null && StrUtil.isNotEmpty(appointChannel.toString())) {
            return getBaiduV3AccessTokenChannel(appointChannel);
        } else {
            return getBaiduV3AccessTokenCommon();
        }
    }

    /**
     * 默认渠道
     * @return
     */
    private String getBaiduV3AccessTokenCommon() {
        /* 只有一个token，就不需要轮训了 */
        if (TOKEN_KEY_LIST.size() == 1) {
            //String token = stringRedisTemplate.opsForValue().get(TOKEN_KEY_LIST.get(0));
            String token = hotCacheProvider.get(TOKEN_KEY_LIST.get(0), String.class);
            if (StrUtil.isNotEmpty(token)) {
                return token;
            }
        }
        //TOKEN_KEY_LIST_CHANNEL如果存在多个就可以进行轮流提取
        String token1 = "";
        int ct1 = 1;
        int ct2 = 0;
        for (String key : TOKEN_KEY_LIST) {
            //String token = stringRedisTemplate.opsForValue().get(key);
            String token = hotCacheProvider.get(key, String.class);
            if (StrUtil.isEmpty(token)) {
                continue;
            }
            //先记住第一个token
            if (ct1 == 1) {
                token1 = token;
            }
            //如果最后token跟CURRENT_TOKEN_CHANNEL存的一致就取第一个token
            if (TOKEN_KEY_LIST.size() == ct1 && token.equals(CURRENT_TOKEN)) {
                CURRENT_TOKEN_CHANNEL = token1;
                return token1;
            }
            if (token.equals(CURRENT_TOKEN)) {
                ct2 = ct1;
            }
            //当token跟CURRENT_TOKEN_CHANNEL存的一致就取下一个循环的token并且这个token跟CURRENT_TOKEN_CHANNEL存的必须不一致
            if (ct2 != 0 && ct1 > ct2 && !token.equals(CURRENT_TOKEN)) {
                CURRENT_TOKEN = token;
                return token;
            }
            ct1++;
        }

        /* 设置token */
        String clients = ConfigUtil.getValue(CommonConst.BAIDU_FACE_ACCOUNT);
        Map<String, String> baiduAccountMap = Maps.newHashMap();
        if (StrUtil.isNotEmpty(clients)) {
            List<String> accountList = StrSpliter.split(clients, ";", true, true);
            for (String accountInfo : accountList) {
                List<String> accountInfoList = StrSpliter.split(accountInfo, ",", true, true);
                baiduAccountMap.put(accountInfoList.get(0), accountInfoList.get(1));
            }
        }

        String redisKey = PublicConst.REDIS_HEAD + "BaiduTokenV3";
        int count = 1;
        for (String key : baiduAccountMap.keySet()) {
            Map<String, String> resultMap = postBaiduToken(key, baiduAccountMap.get(key));
            if (resultMap.isEmpty()) {
                continue;
            }
            String accessToken = resultMap.get("accessToken");
            String expiresIn = resultMap.get("expiresIn");
            /* 百度的token失效时间- 随机秒数 ***/
            long expiresTime = Long.parseLong(expiresIn) - RandomUtil.randomInt(1000);
            if (expiresTime > 0) {
                //stringRedisTemplate.opsForValue().set(redisKey + "_" + count, accessToken, expiresTime, TimeUnit.SECONDS);
                this.hotCacheProvider.put(redisKey + "_" + count, expiresTime, accessToken, true);
                TOKEN_KEY_LIST.add(redisKey + "_" + count);
                count++;
            }
        }

        if (CollUtil.isEmpty(TOKEN_KEY_LIST)) {
            return null;
        }
        //String initToken = stringRedisTemplate.opsForValue().get(TOKEN_KEY_LIST.get(0));
        String initToken = hotCacheProvider.get(TOKEN_KEY_LIST.get(0), String.class);
        CURRENT_TOKEN = initToken;
        return initToken;
    }

    /**
     * 指定渠道token
     * @param appointChannel
     * @return
     */
    private String getBaiduV3AccessTokenChannel(Object appointChannel){
        logger.debug("TOKEN_KEY_LIST_CHANNEL:{}",TOKEN_KEY_LIST_CHANNEL);
        /* 只有一个token，就不需要轮训了 */
        if (TOKEN_KEY_LIST_CHANNEL.size() == 1) {
            //String token = stringRedisTemplate.opsForValue().get(TOKEN_KEY_LIST_CHANNEL.get(0));
            String token = hotCacheProvider.get(TOKEN_KEY_LIST_CHANNEL.get(0),String.class);
            if (StrUtil.isNotEmpty(token)) {
                return token;
            }
        }
        //TOKEN_KEY_LIST_CHANNEL如果存在多个就可以进行轮流提取
        String token1="";
        int ct1=1;
        int ct2=0;
        for (String key : TOKEN_KEY_LIST_CHANNEL) {
            //String token = stringRedisTemplate.opsForValue().get(key);
            String token = hotCacheProvider.get(key,String.class);
            if (StrUtil.isEmpty(token)) {
                continue;
            }
            //先记住第一个token
            if(ct1 == 1){
                token1 = token;
            }
            //如果最后token跟CURRENT_TOKEN_CHANNEL存的一致就取第一个token
            if(TOKEN_KEY_LIST_CHANNEL.size()==ct1&&token.equals(CURRENT_TOKEN_CHANNEL)){
                CURRENT_TOKEN_CHANNEL = token1;
                return token1;
            }
            if(token.equals(CURRENT_TOKEN_CHANNEL)){
                ct2 = ct1;
            }
            //当token跟CURRENT_TOKEN_CHANNEL存的一致就取下一个循环的token并且这个token跟CURRENT_TOKEN_CHANNEL存的必须不一致
            if (ct2!=0&&ct1>ct2&&!token.equals(CURRENT_TOKEN_CHANNEL)) {
                CURRENT_TOKEN_CHANNEL = token;
                return token;
            }
            ct1++;
        }

        /* 设置token */
        String clients = ConfigUtil.getValue(CommonConst.BAIDU_FACE_ACCOUNT + "_" + appointChannel.toString());
        Map<String,String> baiduAccountMap = Maps.newHashMap();
        if (StrUtil.isNotEmpty(clients)) {
            List<String> accountList = StrSpliter.split(clients,";",true,true);
            for (String accountInfo : accountList) {
                List<String> accountInfoList = StrSpliter.split(accountInfo,",",true,true);
                baiduAccountMap.put(accountInfoList.get(0),accountInfoList.get(1));
            }
        }

        String redisKey = PublicConst.REDIS_HEAD + "BaiduTokenV3Channel";
        int count = 1;
        for (String key:baiduAccountMap.keySet()) {
            Map<String,String> resultMap = postBaiduToken(key,baiduAccountMap.get(key));
            if (resultMap.isEmpty()) {
                continue;
            }
            String accessToken = resultMap.get("accessToken");
            String expiresIn = resultMap.get("expiresIn");
            /* 百度的token失效时间- 随机秒数 ***/
            long expiresTime = Long.parseLong(expiresIn) - RandomUtil.randomInt(1000);
            if (expiresTime > 0) {
                //stringRedisTemplate.opsForValue().set(redisKey + "_" + count, accessToken, expiresTime, TimeUnit.SECONDS);
                hotCacheProvider.put(redisKey + "_" + count, expiresTime, accessToken, true);
                TOKEN_KEY_LIST_CHANNEL.add(redisKey + "_" + count);
                count ++;
            }
        }
        if (CollUtil.isEmpty(TOKEN_KEY_LIST_CHANNEL)) {
            return null;
        }
        //String initToken = stringRedisTemplate.opsForValue().get(TOKEN_KEY_LIST_CHANNEL.get(0));
        String initToken = hotCacheProvider.get(TOKEN_KEY_LIST_CHANNEL.get(0),String.class);
        CURRENT_TOKEN_CHANNEL = initToken;
        return initToken;
    }

    /**
     * <b> 获取百度身份证识别应用access_token </b>
     *
     * @author ZXF
     * @create 2020/10/27 0027 16:50
     * @version
     * @注意事项 </b>
     */
    public String getBaiduORCAccessToken() {
        for (String key : ORC_TOKEN_KEY_LIST) {
            //String token = stringRedisTemplate.opsForValue().get(key);
            String token = hotCacheProvider.get(key, String.class);
            if (StrUtil.isEmpty(token)) {
                continue;
            }
            if (!token.equals(ORC_CURRENT_TOKEN)) {
                ORC_CURRENT_TOKEN = token;
                return token;
            }
        }
        /* 只有一个token，就不需要轮训了 */
        if (ORC_TOKEN_KEY_LIST.size() == 1) {
            //String token = stringRedisTemplate.opsForValue().get(ORC_TOKEN_KEY_LIST.get(0));
            String token = hotCacheProvider.get(ORC_TOKEN_KEY_LIST.get(0), String.class);
            if (StrUtil.isNotEmpty(token)) {
                return token;
            }
        }

        /* 设置token */
        String clients = ConfigUtil.getValue(CommonConst.BAIDU_ORC_ACCOUNT);
        Map<String, String> baiduAccountMap = Maps.newHashMap();
        if (StrUtil.isNotEmpty(clients)) {
            List<String> accountList = StrSpliter.split(clients, ";", true, true);
            for (String accountInfo : accountList) {
                List<String> accountInfoList = StrSpliter.split(accountInfo, ",", true, true);
                baiduAccountMap.put(accountInfoList.get(0), accountInfoList.get(1));
            }
        }

        String redisKey = PublicConst.REDIS_HEAD + "BaiduTokenORC";
        int count = 1;
        for (String key : baiduAccountMap.keySet()) {
            Map<String, String> resultMap = postBaiduToken(key, baiduAccountMap.get(key));
            if (resultMap.isEmpty()) {
                continue;
            }
            String accessToken = resultMap.get("accessToken");
            String expiresIn = resultMap.get("expiresIn");
            /* 百度的token失效时间- 随机秒数 ***/
            long expiresTime = Long.parseLong(expiresIn) - RandomUtil.randomInt(1000);
            if (expiresTime > 0) {
                //stringRedisTemplate.opsForValue().set(redisKey + "_" + count, accessToken, expiresTime, TimeUnit.SECONDS);
                hotCacheProvider.put(redisKey + "_" + count, expiresTime, accessToken, true);
                ORC_TOKEN_KEY_LIST.add(redisKey + "_" + count);
                count++;
            }
        }

        if (CollUtil.isEmpty(ORC_TOKEN_KEY_LIST)) {
            return null;
        }
        //return stringRedisTemplate.opsForValue().get(ORC_TOKEN_KEY_LIST.get(0));

        return hotCacheProvider.get(ORC_TOKEN_KEY_LIST.get(0), String.class);
    }

    /**
     * <b> 获取百度头像前景抠图应用access_token </b>
     *
     * @author ZXF
     * @create 2020/10/27 0027 16:50
     * @version
     * @注意事项 </b>
     */
    public String getBaiduKTAccessToken() {
        for (String key : KT_TOKEN_KEY_LIST) {
            //String token = stringRedisTemplate.opsForValue().get(key);
            String token = hotCacheProvider.get(key,String.class);
            if (StrUtil.isEmpty(token)) {
                continue;
            }
            if (!token.equals(KT_CURRENT_TOKEN)) {
                KT_CURRENT_TOKEN = token;
                return token;
            }
        }
        /* 只有一个token，就不需要轮训了 */
        if (KT_TOKEN_KEY_LIST.size() == 1) {
            // String token = stringRedisTemplate.opsForValue().get(KT_TOKEN_KEY_LIST.get(0));
            String token = hotCacheProvider.get(KT_TOKEN_KEY_LIST.get(0),String.class);
            if (StrUtil.isNotEmpty(token)) {
                return token;
            }
        }

        /* 设置token */
        String clients = ConfigUtil.getValue(CommonConst.BAIDU_KT_ACCOUNT);
        Map<String,String> baiduAccountMap = Maps.newHashMap();
        if (StrUtil.isNotEmpty(clients)) {
            List<String> accountList = StrSpliter.split(clients,";",true,true);
            for (String accountInfo : accountList) {
                List<String> accountInfoList = StrSpliter.split(accountInfo,",",true,true);
                baiduAccountMap.put(accountInfoList.get(0),accountInfoList.get(1));
            }
        }

        String redisKey = PublicConst.REDIS_HEAD + "BaiduTokenKT";
        int count = 1;
        for (String key:baiduAccountMap.keySet()) {
            Map<String,String> resultMap = postBaiduToken(key,baiduAccountMap.get(key));
            if (resultMap.isEmpty()) {
                continue;
            }
            String accessToken = resultMap.get("accessToken");
            String expiresIn = resultMap.get("expiresIn");
            /* 百度的token失效时间- 随机秒数 ***/
            long expiresTime = Long.parseLong(expiresIn) - RandomUtil.randomInt(1000);
            if (expiresTime > 0) {
                // stringRedisTemplate.opsForValue().set(redisKey + "_" + count, accessToken, expiresTime, TimeUnit.SECONDS);
                hotCacheProvider.put(redisKey + "_" + count, expiresTime, accessToken, true);
                KT_TOKEN_KEY_LIST.add(redisKey + "_" + count);
                count ++;
            }
        }
        if (CollUtil.isEmpty(KT_TOKEN_KEY_LIST)) {
            return null;
        }
        //return stringRedisTemplate.opsForValue().get(KT_TOKEN_KEY_LIST.get(0));

        return hotCacheProvider.get(KT_TOKEN_KEY_LIST.get(0),String.class);
    }


    private Map<String,String> postBaiduToken(String clientId,String clientSecret){
        /*** 调用百度接口 ***/
        String result = "";
        String getAccessTokenUrl = ConfigUtil.getValue(CommonConst.BAIDU_ACCESS_TOKEN) + "?"
                + "grant_type=" + ConfigUtil.getValue(CommonConst.BAIDU_GRANT_TYPE)
                + "&client_id=" + clientId
                + "&client_secret=" + clientSecret;


        /*
        BufferedReader in = null;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close(); // 输入流关闭
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
         */
        result =com.bcxin.identify.util.baidu.v3.HttpUtil.doGet(getAccessTokenUrl);
        Map<String,String> map = Maps.newHashMap();
        if (StringUtil.isNotEmpty(result)) {
            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
            if (resultMap != null && StringUtil.isNotEmpty(resultMap.get("access_token").toString())) {
                map.put("accessToken",resultMap.get("access_token").toString());
                map.put("expiresIn",resultMap.get("expires_in").toString());
            }
        }
        return map;
    }

    /**
     * 获取腾讯sig
     *
     * @param identifier
     * @return sig
     * @auth zxf
     * @date 2020-05-06
     */
    public String getTencentAdminSig(String identifier) {

        String redisKey = PublicConst.REDIS_HEAD + "TC_ADMIN_SIGN_" + identifier;
        String sig = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            BufferedReader br = null;
            try {
                // 创建应用时，页面上分配的 sdkappid
                String sdkAppid = ConfigUtil.getValue(CommonConst.TENCENT_SDKAPPID);
                // 私钥
                String private_key_url = ConfigUtil.getValue(CommonConst.TENCENT_EC_KEY);
                New_TLSSigAPIv2 ntls = new New_TLSSigAPIv2(Long.parseLong(sdkAppid), private_key_url);
                sig = ntls.genUserSig(identifier, PublicConst.IM_SIG_TIMEOUT);
            } catch (Exception e) {

            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                    }
                }
            }
            if (StringUtils.isNotEmpty(sig)) {
                stringRedisTemplate.opsForValue().set(redisKey, sig, PublicConst.ONE_DAY_TIMEOUT, TimeUnit.MILLISECONDS);
            }
        } else {
            sig = stringRedisTemplate.opsForValue().get(redisKey);
        }
        return sig;
    }

    /**
     * <b> 判断是否有sig缓存 </b>
     * @author ZXF
     * @create 2021/05/19 0019 14:53
     * @version
     * @注意事项 </b>
     */
    public boolean isTencentSig(String identifier) {
        String redisKey = PublicConst.REDIS_HEAD + "TC_SIGN_" + identifier;
        if (!stringRedisTemplate.hasKey(redisKey)) {
            return false;
        }
        return true;
    }

    /**
     * 获取腾讯sig
     *
     * @param identifier
     * @return sig
     * @auth zxf
     * @date 2020-05-06
     */
    public Result getTencentSig(String identifier) {
        String redisKey = PublicConst.REDIS_HEAD + "TC_SIGN_" + identifier;
        String sig = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            BufferedReader br = null;
            try {
                // 创建应用时，页面上分配的 sdkappid
                String sdkAppid = ConfigUtil.getValue(CommonConst.TENCENT_SDKAPPID);
                // 私钥
                String private_key_url = ConfigUtil.getValue(CommonConst.TENCENT_EC_KEY);
                New_TLSSigAPIv2 ntls = new New_TLSSigAPIv2(Long.parseLong(sdkAppid), private_key_url);
                sig = ntls.genUserSig(identifier, PublicConst.IM_SIG_TIMEOUT);
            } catch (Exception e) {
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                    }
                }
            }
            if (StringUtils.isNotEmpty(sig)) {
                stringRedisTemplate.opsForValue().set(redisKey, sig, PublicConst.ONE_HOUR_TIMEOUT_SECONDS, TimeUnit.MILLISECONDS);
            }
        } else {
            sig = stringRedisTemplate.opsForValue().get(redisKey);
        }
        if (StringUtil.isNotEmpty(sig)) {
            return Result.success(Result.SUCCESS_MSG,sig);
        }
        return Result.fail("腾讯SIG获取失败");
    }

    public boolean isYSPSig(String identifier) {
        String redisKey = PublicConst.REDIS_HEAD + "TC_YSP_SIGN_" + identifier;
        if (!stringRedisTemplate.hasKey(redisKey)) {
            return false;
        }
        return true;
    }

    /**
     * 获取腾讯音视频 sig
     *
     * @param identifier
     * @return sig
     * @auth zxf
     * @date 2020-05-06
     */
    public String getYSPSig(String identifier) {
        String redisKey = PublicConst.REDIS_HEAD + "TC_YSP_SIGN_" + identifier;
        String sig = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            BufferedReader br = null;
            try {
                // 创建应用时，页面上分配的 sdkappid
                String sdkAppid = ConfigUtil.getValue(CommonConst.TENCENT_SDKAPPID);
                // 私钥
                String private_key_url = ConfigUtil.getValue(CommonConst.TENCENT_EC_KEY);
                New_TLSSigAPIv2 ntls = new New_TLSSigAPIv2(Long.parseLong(sdkAppid), private_key_url);
                sig = ntls.genUserSig(identifier, PublicConst.IM_SIG_TIMEOUT);
            } catch (Exception e) {
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                    }
                }
            }
            if (StringUtils.isNotEmpty(sig)) {
                stringRedisTemplate.opsForValue().set(redisKey, sig, PublicConst.ONE_HOUR_TIMEOUT_SECONDS, TimeUnit.MILLISECONDS);
            }
        } else {
            sig = stringRedisTemplate.opsForValue().get(redisKey);
        }
        return sig;
    }


    /**
     * 获取华为云会议acessToken
     *
     * @param userName
     * @param passWord
     * @return accessToken
     * @auth zxf
     * @date 2019-12-12
     */
    public String getHuaweiMeetAccessToken(String userName, String passWord) {
        String redisKey = PublicConst.REDIS_HEAD + "HUAWEIMEET_" + userName;
        String accessToken = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            String authorization = Base64.getEncoder().encodeToString((userName + ":" + passWord).getBytes());
            Map<String, Object> map = new HashMap<>();
            map.put("account", userName);
            map.put("clientType", 0);
            map.put("createTokenType", 0);
            String url = HuaweiMeetConst.GATEWAY_URL + HuaweiMeetConst.GET_ACCESSTOKEN;
            Map<String, String> headMap = new HashMap<>();
            headMap.put("Authorization", "Basic " + authorization);
            RestRequest restRequest = HttpBuildUtil.buildRestRequest("POST", headMap, JSON.toJSONString(map), null);
            RestResponse response = HttpBuildUtil.sendMsg(url, restRequest);
            if (response.getHttpCode() == HuaweiMeetConst.HUAWEI_SUCCESS_CODE) {
                Map<String, Object> resultMap = JSON.parseObject(response.getEntity().toString(), Map.class);
                if (resultMap != null) {
                    accessToken = resultMap.get("accessToken").toString();
                    String expires_in = resultMap.get("validPeriod").toString();
                    /*** 华为云token失效时间- 一小时 ***/
                    Long expiresTime = Long.parseLong(expires_in) - 3600L;
                    if (expiresTime > 0) {
                        stringRedisTemplate.opsForValue().set(redisKey, accessToken, expiresTime, TimeUnit.SECONDS);
                    }
                }
            }
        } else {
            accessToken = stringRedisTemplate.opsForValue().get(redisKey);
        }
        return accessToken;
    }

    /**
     * 获取企业管理员华为云会议acessToken
     *
     * @param userName
     * @param passWord
     * @return accessToken
     * @auth llc
     * @date 2019-12-18
     */
    public String getComManageHuaweiMeetAccessToken(String userName, String passWord) {
        String redisKey = PublicConst.REDIS_HEAD + "HUAWEIMEET_COM_" + userName;
        String accessToken = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            String authorization = Base64.getEncoder().encodeToString((userName + ":" + passWord).getBytes());
            Map<String, Object> map = new HashMap<>();
            map.put("account", userName);
            map.put("clientType", 0);
            map.put("createTokenType", 0);
            String url = HuaweiMeetConst.GATEWAY_URL + HuaweiMeetConst.GET_ACCESSTOKEN;
            Map<String, String> headMap = new HashMap<>();
            headMap.put("Authorization", "Basic " + authorization);
            RestRequest restRequest = HttpBuildUtil.buildRestRequest("POST", headMap, JSON.toJSONString(map), null);
            RestResponse response = HttpBuildUtil.sendMsg(url, restRequest);
            System.out.println("getComManageHuaweiMeetAccessToken => response:" + response.toString());
            if (response.getHttpCode() == HuaweiMeetConst.HUAWEI_SUCCESS_CODE) {
                Map<String, Object> resultMap = JSON.parseObject(response.getEntity().toString(), Map.class);
                if (resultMap != null) {
                    accessToken = resultMap.get("accessToken").toString();
                    String expires_in = resultMap.get("validPeriod").toString();
                    /*** 华为云token失效时间- 一小时 ***/
                    Long expiresTime = Long.parseLong(expires_in) - 3600L;
                    if (expiresTime > 0) {
                        stringRedisTemplate.opsForValue().set(redisKey, accessToken, expiresTime, TimeUnit.SECONDS);
                    }
                }
            }
        } else {
            accessToken = stringRedisTemplate.opsForValue().get(redisKey);
            logger.info("从缓存中拿accessToken:" + accessToken);
        }
        return accessToken;
    }

    /**
     * <b> 个推获取token </b>
     * @author ZXF
     * @create 2021/05/11 0011 15:33
     * @version
     * @注意事项 </b>
     */
    public String getGeTuiToken() {
        String redisKey = PublicConst.REDIS_HEAD + "GETUI_TOKEN";
        String sig = "";
        if (!stringRedisTemplate.hasKey(redisKey)) {
            Result ret = GeTuiUtil.auth();
            if(!Result.ERROR.equals(ret.getRetType())){
                JSONObject j = (JSONObject) ret.getData();
                String expiresIn = j.get("expire_time").toString();
                String accessToken = j.get("token").toString();
                /* token失效时间- 随机秒数 ***/
                long expiresTime = Long.parseLong(expiresIn)/1000 - 1000;
                if (expiresTime > 0) {
                    stringRedisTemplate.opsForValue().set(redisKey, accessToken, expiresTime, TimeUnit.SECONDS);
                }
                sig = accessToken;
            }
        } else {
            sig = stringRedisTemplate.opsForValue().get(redisKey);
        }
        return sig;
    }

    public void delGeTuiTokenCache() {
        deleteRedisByKey("GETUI_TOKEN");
    }

    /**
     * <b> 设置房间人数 </b>
     *
     * @param room  房间号
     * @param count 人数
     * @author ZXF
     * @create 2020/07/10 0010 13:37
     * @version
     * @注意事项 </b>
     */
    public boolean setRoomPerNum(String room, String count) {
        if (StringUtils.isNotEmpty(count) && StringUtils.isNotEmpty(room)) {
            String redisKey = PublicConst.REDIS_HEAD + "room_" + room;
            logger.info("设置房间人数（" + redisKey + "）:" + count);
            stringRedisTemplate.opsForValue().set(redisKey, count, PublicConst.ONE_DAY_TIMEOUT, TimeUnit.MILLISECONDS);
            return true;
        }
        return false;
    }

    /**
     * <b> 获取房间人数 </b>
     *
     * @return 人数#是否解散房间（字符串直接拼接）
     * @author ZXF
     * @create 2020/07/10 0010 13:38
     * @version
     * @注意事项 </b>
     */
    public String getRoomPerNum(String room) {
        String redisKey = PublicConst.REDIS_HEAD + "room_" + room;
        String count = stringRedisTemplate.opsForValue().get(redisKey);
        logger.info("获取房间人数（" + redisKey + "）:" + count);
        return stringRedisTemplate.opsForValue().get(PublicConst.REDIS_HEAD + "room_" + room);
    }

    /**
     * <b> 解散房间时删除房间redis记录 </b>
     *
     * @author ZXF
     * @create 2020/08/20 0020 10:27
     * @version
     * @注意事项 </b>
     */
    public void delRoom(String room) {
        String redisKey = PublicConst.REDIS_HEAD + "room_" + room;
        logger.info("解散房间（" + redisKey + "）--------------");
        getRoomPerNum(room);
        stringRedisTemplate.delete(redisKey);
    }

    /**
     * <b> 通过接口删除redisKey方便下次加载
     *      * 由于redisKey对应的value存在变动手动删除不方便 </b>
     * @author ZXF
     * @create 2021/05/17 0017 16:22
     * @version
     * @注意事项 </b>
     */
    public Result deleteRedisByKey(String key) {
        String redisKey = PublicConst.REDIS_HEAD + key;
        /*** 如果存在key就删除 ***/
        if (stringRedisTemplate.hasKey(redisKey)) {
            stringRedisTemplate.delete(redisKey);
        }
        return Result.success(Result.SUCCESS_QUERY_MSG);
    }

    public void gtSendMsg(Map<String,Object> params) {
        String orgId = String.valueOf(params.get("orgId"));
        String param = String.valueOf(params.get("param"));
        String cuList = String.valueOf(params.get("cuList"));// cid;uid,cid;uid
        String title = String.valueOf(params.get("title"));
        String body = String.valueOf(params.get("body"));
        String payload = String.valueOf(params.get("payload"));

        String[] list = cuList.split(",");
        Result getRet;
        for (String str : list) {
            String[] uTemp = str.split(";");
            JSONObject json = new JSONObject();
            json.put("orgId", orgId);
            json.put("useId", uTemp[1]);
            json.put("param", param);
            String content = json.toJSONString();
            String[] cids = {uTemp[0]};
            String token = getGeTuiToken();
            getRet = GeTuiUtil.pushSingleCom(-1, cids, token, content, title, body, payload);
            if(GTErrorEnum.ERROR_10001.getError_msg().equals(getRet.getMsg())){
                delGeTuiTokenCache();
            }
        }
    }
}