package com.yutou.qqbot.utlis;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;


public class RedisTools {
    public static final int QQBOT_USER = 3;
    private static boolean isNotInstallRedis = false;
    private static String host;
    private static int port;
    public static int TOKEN_TIMEOUT_DEFAULT = 360;
    public final static int DATABASES_ALI_OSS = 4;

    private RedisTools() {

    }

    // 写成静态代码块形式，只加载一次，节省资源
    static {
        //Properties properties = PropertyUtil.loadProperties("jedis.properties");
        //host = properties.getProperty("redis.host");
        //port = Integer.valueOf(properties.getProperty("redis.port"));
        host = "localhost";
        port = 6379;
    }

    public static boolean set(int dbIndex, String key, String value) {
        try {
            if (isNotInstallRedis) {
                return false;
            }
            Jedis jedis = getRedis();
            jedis.select(dbIndex);
            String ret = jedis.set(key, value);
            //Log.i("Redis set =" + ret,"key = "+key+" value = "+value);
            jedis.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static boolean set(String key, String value, long timeout, int db) {
        try {
            if (isNotInstallRedis) {
                return false;
            }
            Jedis jedis = getRedis();
            if (db > -1) {
                jedis.select(db);
            }
            if (timeout == -1) {
                jedis.set(key, value);
            } else {
                jedis.setex(key, timeout, value);
            }
            jedis.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static boolean set(Object key, String value) {
        return set(QQBOT_USER, key + "", value);
    }

    public static boolean set(String key, String value, long timeout) {
        return set(key, value, timeout, QQBOT_USER);
    }

    public static String get(String key, int dbIndex) {
        String value = null;
        if (isNotInstallRedis) {
            return value;
        }
        try (Jedis jedis = getRedis()) {
            jedis.select(dbIndex);
            value = jedis.get(key);
            jedis.close();
        } catch (Exception e) {
            // TODO: handle exception
            //	e.printStackTrace();
        }
        return value;
    }

    public static String get(Object key) {
        return get(key + "", QQBOT_USER);
    }

    public static String get(Object key, String defValue) {
        String ret = get(key);
        if (StringUtils.isEmpty(ret)) {
            return defValue;
        }
        return ret;
    }

    public static boolean remove(String key) {
        return remove(key, QQBOT_USER);
    }

    public static void removeLoginState(String uid) {
        Jedis jedis = getRedis();
        Set<String> keys = jedis.keys("*");
        for (String string : keys) {
            if (string.equals(uid)) {
                jedis.del(string);
            }
        }

    }

    public static String ping() {
        Jedis jedis = getRedis();
        String tmp = jedis.ping();
        jedis.close();
        return tmp;
    }

    public static boolean exists(Object key, String value) {
        return exists(QQBOT_USER, key, value);
    }

    public static boolean exists(int db, Object key, String value) {
        if (isNotInstallRedis) {
            return false;
        }
        Jedis jedis = getRedis();
        jedis.select(db);
        boolean flag = false;
        if (value == null) {
            flag = jedis.exists(key + "");
        } else {
            flag = value.equals(jedis.get(key + ""));
        }
        jedis.close();
        return flag;
    }

    public static long list_add(String listName, String... value) {
        Jedis jedis = getRedis();
        jedis.select(QQBOT_USER);
        long index = jedis.sadd(listName, value);
        jedis.close();
        return index;
    }

    public static Set<String> list_get(String listName) {
        Set<String> set;
        try {
            Jedis jedis = getRedis();
            jedis.select(QQBOT_USER);
            set = jedis.smembers(listName);
            jedis.close();
            if (set == null) {
                set = new HashSet<>();
            }
        } catch (Exception e) {
            e.printStackTrace();
            set = new HashSet<>();
        }

        return set;
    }

    public static boolean list_remove(String listName, String... value) {
        long index = 0;
        try {
            Jedis jedis = getRedis();
            jedis.select(QQBOT_USER);
            index = jedis.srem(listName, value);
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return index != 0;
    }

    public static boolean list_isExist(String listName, String value) {
        boolean flag = false;
        try {
            Jedis jedis = getRedis();
            flag = jedis.sismember(listName, value);
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static String getHashMap(String hashKey, String key) {
        Jedis jedis = getRedis();
        return jedis.hget(hashKey, key);
    }

    public static Map<String, String> getHashMap(String hashKey) {
        return getRedis().hgetAll(hashKey);
    }

    public static boolean setHashMap(String hashKey, String key, String value) {
        Jedis jedis = getRedis();
        long l = jedis.hset(hashKey, key, value);
        jedis.close();
        return l == 0;
    }

    public static boolean removeHashMap(String hashKey, String key) {
        Jedis jedis = getRedis();
        long l = jedis.hdel(hashKey, key);
        jedis.close();
        return l > 0;
    }

    public static boolean removeHashMap(String hashKey) {
        Jedis jedis = getRedis();
        long del = jedis.del(hashKey);
        return del > 0;

    }

    public static Jedis getRedis() {
        Jedis jedis = new Jedis(host, port);
        jedis.select(QQBOT_USER);
        return jedis;
    }

    public static boolean remove(String key, int index) {
        if (isNotInstallRedis) {
            return false;
        }
        Jedis jedis = getRedis();
        jedis.select(index);
        long i = jedis.del(key);
        jedis.close();
        return i > 0;
    }

    private static class PropertyUtil {

        // 加载property文件到io流里面
        public static Properties loadProperties(String propertyFile) {
            Properties properties = new Properties();
            try {
                InputStream is = PropertyUtil.class.getClassLoader().getResourceAsStream(propertyFile);
                if (is == null) {
                    is = PropertyUtil.class.getClassLoader().getResourceAsStream(propertyFile);
                }
                properties.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return properties;
        }
    }

    private static Jedis getPoolRedis() {
        if (isNotInstallRedis) {
            return null;
        }
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(0);
        poolConfig.setMaxWaitMillis(1000);
        JedisPool pool = new JedisPool();
        return pool.getResource();
    }

    public static void pullMsg(String channel, String msg) {
        Jedis jedis = getPoolRedis();
        jedis.publish(channel, msg);
        jedis.close();
    }

    private static boolean init = false;

    public static void initRedisPoolSub() {
        if (init) {
            return;
        }
        init = true;
        Log.i("初始化订阅");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Jedis jedis = getPoolRedis();
                if (jedis != null) {
                    jedis.psubscribe(new Consumer(), "*");
                }
            }
        }).start();

    }

    public static class Consumer extends JedisPubSub {
        @Override
        public void onPMessage(String pattern, String channel, String message) {
            super.onPMessage(pattern, channel, message);
            Log.i("onPMessage: channel=" + channel + " msg=" + message + " pattern=" + pattern);
            switch (channel) {
                case "system":
                    switch (message) {
                        case "openPC":
                            system("openPC", null);
                            break;
                        case "updateIP":
                            system("updateIP", null);
                            break;
                    }
                    break;
                case "bot":
                    bot(message);
                    break;
                case "cmd":
                    system("cmd", message);
                    break;
                case "msg":
                    AppTools.sendServer("来自服务姬的通知~", message);
                    break;
            }
        }

        @Override
        public void onMessage(String channel, String message) {
            super.onMessage(channel, message);
            Log.i("onMessage: channel=" + channel + " msg=" + message);
        }

        public static void system(String type, String value) {
            try {
                String exec = null;
                switch (type) {
                    case "openPC":
                        exec = "wakeonlan 00:D8:61:6F:02:2F";
                        break;
                    case "cmd":
                        exec = value;
                        break;
                    case "updateIP":
                        exec = "python3 /media/yutou/disk_lvm/public/Python/tools/ip.py";
                        break;
                }
                if (exec != null) {
                    Process process = Runtime.getRuntime().exec(exec);
                    processOut(process.getInputStream());
                    processOut(process.getErrorStream());
                    process.destroy();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        public static void bot(String value) {
            switch (value) {
                case "getip":
                    JSONObject json = JSON.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
                    String ip = json.getString("ip");
                    QQBotManager.getInstance().sendMessage("服务器IP:\n" + ip);
                    break;
            }
        }
    }

    public static void processOut(InputStream inputStream) {
        processOut(inputStream, null, true);
    }

    public static void processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot) {
        String tmp;
        StringBuilder str = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            while ((tmp = reader.readLine()) != null) {
                str.append(tmp).append("\n");
            }
            reader.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (objectInterface != null) {
            objectInterface.out(str.toString());
        }
        //  Log.i("cmd > " + str);
        if (isOutQQBot) {
            QQBotManager.getInstance().sendMessage(str.toString());
        }
    }

    public static void main(String[] args) {
        //  RedisTools.pullMsg("msg", "abc");
        RedisTools.set("test", "abc");
    }
}
