package org.ts.ddcs.Worker;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.ts.ddcs.Log.LogHelper;
import org.ts.ddcs.utils.GBConstants;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;
import java.util.concurrent.Callable;

@SuppressWarnings("all")
public class DataConnectManageProcess implements Callable<Integer> {

    private String rtuCode;
    private String serverId;
    private Date dt;

    DataConnectManageProcess(String rtuCode, String serverId, Date dt) {
        this.dt = dt;
        this.rtuCode = rtuCode;
        this.serverId = serverId;
    }


    @Override
    public Integer call() throws Exception {
        try {
            RedisTemplate redisTemplate = DataProcessHolder.newInstance().dataProcess.redisTemplate;
            HashOperations<String, String, String> opsHash = redisTemplate.opsForHash();

            int ave_healt = 0;
            if (opsHash.hasKey(rtuCode, GBConstants.BASE_KEY_COLLECT_SERVER_GROUP)) {
                String servers = opsHash.get(rtuCode, GBConstants.BASE_KEY_COLLECT_SERVER_GROUP);
                JSONArray serverArr = JSONArray.parseArray(servers);
                boolean find = false;
                for (Object s : serverArr) {
                    JSONObject connectInfo = (JSONObject) s;
                    String id = (String) connectInfo.get("id");
                    if (null != id && id.equals(serverId)) {
                        connectInfo.put("lastTime", new Date().getTime());
                        find = true;
                        break;
                    }
                }
                if (!find) {
                    JSONObject connectInfo = new JSONObject();
                    connectInfo.put("lastTime", new Date().getTime());
                    connectInfo.put("healt", (long) 100);
                    connectInfo.put("id", serverId);
                    serverArr.add(connectInfo);
                }

                /**生成列表**/
                List<Map<String, Object>> serverList = new LinkedList<>();
                for (Object s : serverArr) {
                    JSONObject connectInfo = (JSONObject) s;
                    String id = (String) connectInfo.get("id");
                    if (null != id) {
                        long lastTime = connectInfo.getLongValue("lastTime");
                        Map<String, Object> map_server = new HashMap<>();
                        map_server.put("id", id);
                        if (id.equals(serverId)) {
                            map_server.put("time", (long) 0);
                        } else {
                            map_server.put("time", (long) (this.dt.getTime() - lastTime));
                        }
                        map_server.put("lastTime", lastTime);
                        map_server.put("healt", (long) connectInfo.getLong("healt"));
                        serverList.add(map_server);
                    }
                }
                /**按报文最近接收时间排序**/
                serverList.sort(new Comparator<Map<String, Object>>() {
                    @Override
                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                        long time1 = (long) o1.get("time");
                        long time2 = (long) o2.get("time");
                        if (time1 > time2) {
                            return 1;
                        } else if (time1 == time2) {
                            return 0;
                        } else {
                            return -1;
                        }
                    }
                });
                /**计算健康度**/
                long correctHealt = 100/serverList.size();
                long  index = serverList.size();
                for (Map<String, Object> m : serverList) {
                    long h = ((long) m.get("healt") + correctHealt*index)/2;
                    m.put("healt", (long) h);
                    index -= 1;
                }
                /**按健康度排序**/
                serverList.sort(new Comparator<Map<String, Object>>() {
                    @Override
                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                        long h1 = (long) o1.get("healt");
                        long h2 = (long) o2.get("healt");
                        if (h1 > h2) {
                            return -1;
                        } else if (h1 == h2) {
                            return 0;
                        } else {
                            return 1;
                        }
                    }
                });

                String master = opsHash.get(rtuCode, GBConstants.BASE_KEY_SERVER_MASTER);
                if (null != master) {
                    JSONArray setServerArray = new JSONArray();
                    long masterHealt = 0;
                    for (Map<String, Object> m : serverList) {
                        long h = (long) m.get("healt");
                        String id = (String) m.get("id");
                        if (id.equals(master)) {
                            masterHealt = h;
                        }
                        JSONObject connectInfo = new JSONObject();
                        connectInfo.put("lastTime", (long) m.get("lastTime"));
                        connectInfo.put("healt", h);
                        connectInfo.put("id", id);
                        setServerArray.add(connectInfo);
                    }

                    Map<String, Object> first = serverList.get(0);
                    String firstServer = (String) first.get("id");
                    if (!firstServer.equals(master)) {
                        long firstHealt = (long) first.get("healt");
                        if (firstHealt - masterHealt > 2) {
                            opsHash.put(rtuCode, GBConstants.BASE_KEY_SERVER_MASTER, firstServer);
                        }
                    }
                    opsHash.put(rtuCode, GBConstants.BASE_KEY_COLLECT_SERVER_GROUP, setServerArray.toJSONString());
                } else {
                    Map<String, Object> first = serverList.get(0);
                    String firstServer = (String) first.get("id");
                    opsHash.put(rtuCode, GBConstants.BASE_KEY_SERVER_MASTER, firstServer);
                    JSONArray setServerArray = new JSONArray();
                    for (Map<String, Object> m : serverList) {
                        long h = (long) m.get("healt");
                        String id = (String) m.get("id");
                        JSONObject connectInfo = new JSONObject();
                        connectInfo.put("lastTime", (long) m.get("lastTime"));
                        connectInfo.put("healt", h);
                        connectInfo.put("id", id);
                        setServerArray.add(connectInfo);
                    }
                    opsHash.put(rtuCode, GBConstants.BASE_KEY_COLLECT_SERVER_GROUP, setServerArray.toJSONString());
                }
            } else {
                opsHash.put(rtuCode, GBConstants.BASE_KEY_SERVER_MASTER, serverId);
                JSONObject connectInfo = new JSONObject();
                connectInfo.put("lastTime", new Date().getTime());
                connectInfo.put("healt", (long) 100);
                connectInfo.put("id", serverId);
                JSONArray serverList = new JSONArray();
                serverList.add(connectInfo);
                opsHash.put(rtuCode, GBConstants.BASE_KEY_COLLECT_SERVER_GROUP, serverList.toJSONString());
            }

        } catch (Exception e) {
            LogHelper.error(e);
        }
        return 0;
    }
}
