package com.gyee.frame.util.mongodb;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gyee.frame.common.spring.InitialRunner;
import com.gyee.frame.model.auto.RMConfig;
import com.gyee.frame.model.custom.DNAVal;
import com.gyee.frame.model.custom.PointData;
import com.gyee.frame.util.StringUtils;
import org.apache.commons.collections.map.LinkedMap;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * ClassName:JedisPool <br/>
 *
 * @author 石林
 * @see
 * @since JDK 1.8
 */
@Component
public class JedisPoolUtil {

    @Resource
    @Qualifier("ss_redis")
    private JedisPool jedisPool;// 非切片连接池

    private final Integer ARR_NUM = 18;

    /**
     * 释放jedis资源
     *
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }



    public PointData getRealData(String code) throws IOException {

        PointData po = new PointData();



        Map<String, Response<String>> resmap = new LinkedMap();

        Jedis jedis = jedisPool.getResource();

        Pipeline pipelined = jedis.pipelined();


        if(InitialRunner.rmcmap.containsKey(code))
        {
            RMConfig rmc = InitialRunner.rmcmap.get(code);

            pipelined.select(rmc.getRedisindex());

            resmap.put(code, pipelined.get(code));

            pipelined.sync();

            String result = resmap.get(code).get();


            setPointData(code, rmc, po, result);
        }else
        {

            pipelined.select(ARR_NUM);

            resmap.put(code, pipelined.get(code));

            pipelined.sync();

            String result = resmap.get(code).get();

            if(StringUtils.isNotNull(result))
            {
                setPointData(code,  po, result);
            }

        }

        returnResource(jedis);

        return po;


    }

    @SuppressWarnings("unchecked")
    private void setPointData(String code, RMConfig rmc, PointData po, String result) {
        Map<Object, Object> json = (Map<Object, Object>) JSONObject.parse(result);

        po.setEdnaId(code);

        for (Object map : json.entrySet()) {

            Map.Entry<Object, Object> tempmap = (Map.Entry<Object, Object>) map;
            Long time = Long.valueOf(String.valueOf(tempmap.getKey()));

            Double value = Double.valueOf(String.valueOf(tempmap.getValue()));
            po.setPointValueInDouble(value);
            po.setPointTime(time * 1000);
        }
    }

    private void setPointData(String code, PointData po, String result) {
        Map<Object, Object> json = (Map<Object, Object>) JSONObject.parse(result);

        po.setEdnaId(code);

        for (Object map : json.entrySet()) {

            Map.Entry<Object, Object> tempmap = (Map.Entry<Object, Object>) map;
            Long time = Long.valueOf(String.valueOf(tempmap.getKey()));

            Double value = Double.valueOf(String.valueOf(tempmap.getValue()));
            po.setPointValueInDouble(value);
            po.setPointTime(time * 1000);
        }
    }

    public List<PointData> getRealData(String... key) throws IOException {

        List<PointData> ls = new ArrayList<PointData>();

        if (StringUtils.isNotNull(key) && key.length > 0) {


            Map<String, Response<String>> resmap = new LinkedHashMap<String, Response<String>>();
            Jedis jedis = jedisPool.getResource();

            Pipeline pipelined = jedis.pipelined();
            for (String code : key) {

                if (InitialRunner.rmcmap.containsKey(code)) {

                    RMConfig rmc = InitialRunner.rmcmap.get(code);

                    pipelined.select(rmc.getRedisindex());

                    resmap.put(code, pipelined.get(code));

                }else
                {

                    pipelined.select(ARR_NUM);

                    resmap.put(code, pipelined.get(code));

                }

            }
            pipelined.sync();
            pipelined.close();
            for (String code : resmap.keySet()) {

                String result = resmap.get(code).get();
                if (result != null && result.length() > 0) {
                    PointData po = new PointData();
                    setPointData(code, po, result);
                    ls.add(po);
                }
            }

            returnResource(jedis);
        }

        return ls;
    }

    public List<PointData> getRealData(List<String> key) throws IOException {

        List<PointData> ls = new ArrayList<PointData>();

        if (StringUtils.isNotNull(key) && key.size() > 0) {
            Map<String, Response<String>> resmap = new LinkedHashMap<String, Response<String>>();
            Jedis jedis = jedisPool.getResource();

            Pipeline pipelined = jedis.pipelined();
            for (String code : key) {

                if (InitialRunner.rmcmap.containsKey(code)) {

                    RMConfig rmc = InitialRunner.rmcmap.get(code);

                    pipelined.select(rmc.getRedisindex());

                    resmap.put(code, pipelined.get(code));

                }else
                {

                    pipelined.select(ARR_NUM);

                    resmap.put(code, pipelined.get(code));

                }

            }
            pipelined.sync();
            pipelined.close();
            for (String code : resmap.keySet()) {
                String result = resmap.get(code).get();
                if (result != null && result.length() > 0) {
                    PointData po = new PointData();
                    setPointData(code, po, result);
                    ls.add(po);
                }
            }
            returnResource(jedis);
        }

        return ls;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Double> getRealDataMap(String... key) throws IOException {

        Map<String, Double> map = new LinkedMap();

        if (StringUtils.isNotNull(key) && key.length > 0) {

            Map<String, Response<String>> resmap = new LinkedHashMap<String, Response<String>>();
            Jedis jedis = jedisPool.getResource();

            Pipeline pipelined = jedis.pipelined();
            for (String code : key) {

                if (InitialRunner.rmcmap.containsKey(code)) {

                    RMConfig rmc = InitialRunner.rmcmap.get(code);

                    pipelined.select(rmc.getRedisindex());

                    resmap.put(code, pipelined.get(code));

                }else
                {

                    pipelined.select(ARR_NUM);

                    resmap.put(code, pipelined.get(code));

                }

            }
            pipelined.sync();
            pipelined.close();

            for (String code : resmap.keySet()) {
                String result = resmap.get(code).get();
                if (result != null && result.length() > 0) {
                    Map<Object, Object> json = (Map<Object, Object>) JSONObject.parse(result);

                    Double value = 0.0;
                    for (Object jsonmap : json.entrySet()) {

                        Map.Entry<Object, Object> tempmap = (Map.Entry<Object, Object>) jsonmap;

                        value = Double.valueOf(String.valueOf(tempmap.getValue()));

                    }
                    map.put(code, value);
                }
            }

            returnResource(jedis);
        }

        return map;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Double> getRealDataMap(List<String> key) throws IOException {

        Map<String, Double> map = new LinkedMap();

        if (StringUtils.isNotNull(key) && !key.isEmpty()) {

            Map<String, Response<String>> resmap = new LinkedMap();
            Jedis jedis = jedisPool.getResource();

            Pipeline pipelined = jedis.pipelined();
            for (String code : key) {

                if (InitialRunner.rmcmap.containsKey(code)) {

                    RMConfig rmc = InitialRunner.rmcmap.get(code);

                    pipelined.select(rmc.getRedisindex());

                    resmap.put(code, pipelined.get(code));

                }else
                {

                    pipelined.select(ARR_NUM);

                    resmap.put(code, pipelined.get(code));

                }

            }
            pipelined.sync();
            pipelined.close();

            for (String code : resmap.keySet()) {
                String result = resmap.get(code).get();
                if (result != null && result.length() > 0) {
                    Map<Object, Object> json = (Map<Object, Object>) JSONObject.parse(result);

                    Double value = 0.0;
                    for (Object jsonmap : json.entrySet()) {

                        Map.Entry<Object, Object> tempmap = (Map.Entry<Object, Object>) jsonmap;

                        value = Double.valueOf(String.valueOf(tempmap.getValue()));

                    }
                    map.put(code, value);
                }
            }

            returnResource(jedis);
        }

        return map;
    }


    public Object[] readKeyArray(String key) {

        // 验证
        Jedis jedis = jedisPool.getResource();
        jedis.select(0);
        String result = jedis.get(key);

        JSONArray array = JSONArray.parseArray(result);

        Object[] arr = (Object[]) array.toArray();

        returnResource(jedis);

        return arr;
    }


    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public DNAVal[] getRealtimeTagValues(String... tagNames) throws Exception {

      
        if (StringUtils.isNotNull(tagNames) && tagNames.length>0) {

            DNAVal[] dNAVal=  new DNAVal[tagNames.length];

            Map<String, Response<String>> resmap = new LinkedMap();
            Jedis jedis = jedisPool.getResource();

            Pipeline pipelined = jedis.pipelined();
            for (String code : tagNames) {

                if (InitialRunner.rmcmap.containsKey(code)) {

                    RMConfig rmc = InitialRunner.rmcmap.get(code);

                    pipelined.select(rmc.getRedisindex());

                    resmap.put(code, pipelined.get(code));

                }else
                {

                    pipelined.select(ARR_NUM);

                    resmap.put(code, pipelined.get(code));

                }

            }
            pipelined.sync();
            pipelined.close();

            int i=0;
            for (String code : resmap.keySet()) {
                String result = resmap.get(code).get();
                if (result != null && result.length() > 0) {
                    Map<Object, Object> json = (Map<Object, Object>) JSONObject.parse(result);

                    Double value = 0.0;
                    for (Object jsonmap : json.entrySet()) {

                        Map.Entry<Object, Object> tempmap = (Map.Entry<Object, Object>) jsonmap;


                        Integer time = Integer.valueOf(String.valueOf(tempmap.getKey()));

                        value = Double.valueOf(String.valueOf(tempmap.getValue()));

                        dNAVal[i].Time=time;
                        dNAVal[i].DValue=value;


                    }

                    i++;
                }
            }

            returnResource(jedis);
        }
        return new DNAVal[0];
    }
}
