package com.ruoyi.zhdd.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.zhdd.service.IDhService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO
 * @Author: huangcheng
 * @Date: 2022/1/19
 * @Version V1.0
 */
@Service
@Slf4j
public class DhServiceImpl implements IDhService {

    @Value("${third.dhAuthorize}")
    private String dhAuthorizeUrl;
    @Value("${third.keepalive}")
    private String keepaliveUrl;
    @Value("${third.dhDeviceTree}")
    private String dhDeviceTreeUrl;
    @Autowired
    private ISysConfigService sysConfigService;

    @Override

    public String getToken() {
        String token = RedisUtils.getCacheObject(Constants.CACHE_DH_TOKEN);
        if (token == null) {
            token = authorize();
        }
        return token;
    }

    /**
     * 创建会话
     *
     * @return
     */
    public String authorize() {
        // 从大华接口获取token
        String token = "";
        String userName = "shujuceshi";
        JSONObject jsonOne = new JSONObject();
        jsonOne.set("userName", userName);
        jsonOne.set("clientType", "other");
        String postOne = HttpUtil.post(dhAuthorizeUrl, jsonOne.toString());
        JSONObject postOneJson = JSONUtil.parseObj(postOne);
        if (postOneJson.containsKey("realm")) {
            String randomKey = postOneJson.getStr("randomKey");
            String realm = postOneJson.getStr("realm");
            String encryptType = postOneJson.getStr("encryptType");
            // 第二次交互
            String password = "Admin123";
            String signature = SecureUtil.md5(
                SecureUtil.md5(userName + ":" + realm + ":" +
                    SecureUtil.md5(
                        SecureUtil.md5(
                            userName +
                                SecureUtil.md5(password)))) + ":" + randomKey);
            jsonOne.set("signature", signature);
            jsonOne.set("randomKey", randomKey);
            jsonOne.set("encryptType", encryptType);
            String postTwo = HttpUtil.post(dhAuthorizeUrl, jsonOne.toString());
            JSONObject postTwoJson = JSONUtil.parseObj(postTwo);
            if (postTwoJson.containsKey("token")) {
                token = postTwoJson.getStr("token");
                // 存入redis缓存
                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN, token, 120, TimeUnit.SECONDS);
//                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN_REFRESH, token);
            } else {
                log.error("大华=第二次创建会话失败：{}", postTwoJson);
                if ("user is repeated landing".equals(postTwoJson.getStr("message"))) {
                    // 说明已经登录过，那么退出，重新获取

                }
            }
        } else {
            log.error("大华=第一次创建会话失败：{}", postOneJson);
        }
        return token;
    }

    /**
     * 保活大华token
     *
     * @param token
     */
    public void tokenKeepalive(String token) {
        JSONObject json = new JSONObject();
        json.set("token", token);
        json.set("duration", 120);
        String put = HttpRequest.put(keepaliveUrl).timeout(-1).body(json.toString()).execute().body();
        JSONObject putJson = JSONUtil.parseObj(put);
        if (putJson.getInt("code") == 200) {
            // 存入redis缓存
            RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN, token, 120, TimeUnit.SECONDS);
        } else {
            log.info("保活失败：{}。重新获取", putJson);
            authorize();
        }
    }

    @Override
    public Object getDeviceTree() {
        Map<String, Object> param = new HashMap<>();
        String id = sysConfigService.selectConfigByKey("dh.device.orgId");
        param.put("id", id);
        param.put("nodeType", 1);
        param.put("typeCode", "01;0;ALL;ALL");
        param.put("page", 1);
        param.put("pageSize", 100);
        String get = HttpRequest.get(dhDeviceTreeUrl)
            .header("X-Subject-Token", this.getToken())
            .form(param)
            .timeout(-1)
            .execute().body();
        JSONObject getJson = JSONUtil.parseObj(get);
        if (getJson.containsKey("code")) {
            // 说明有错误
            log.error("获取设备树出错：{}", getJson);
            throw new ServiceException("获取设备树出错.稍后再试");
        }
        return getJson.getJSONArray("results");
    }

}
