package com.zzsn.cache;

import net.rubyeye.xmemcached.KeyIterator;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Author Sugar
 * @Version 2018/6/8 13:22
 */
public class MemcachedAdmin {
    private static Logger logger = LoggerFactory.getLogger(MemcachedAdmin.class);
    private static MemcachedClient client = null;

    private MemcachedAdmin() {

    }

    private static MemcachedClient getClient() {
        if (client != null) {
            return client;
        }
        Properties prop = Memcached.getConfig();
        String server = prop.getProperty("memcached.server");
        if (server == null || server.isEmpty()) {
            throw new IllegalArgumentException("The property 'memcached.server' is not found in memcached.properties file!");
        }
        String[] servers = server.split(",");
        List<InetSocketAddress> addressList = new ArrayList<>(servers.length);
        for (int i = 0; i < servers.length; i++) {
            String[] addr = servers[i].split(":");
            addressList.add(new InetSocketAddress(addr[0], Integer.parseInt(addr[1])));
        }
        XMemcachedClientBuilder builder = new XMemcachedClientBuilder(addressList);
        try {
            client = builder.build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return client;
    }

    @Deprecated
    public static long deleteAll(String keyPrefix) {
        AtomicLong count = new AtomicLong();
        MemcachedClient client = getClient();
        client.getAvailableServers().forEach(inet -> {
            try {
                KeyIterator iterator = client.getKeyIterator(inet);
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    if (key.startsWith(keyPrefix)) {
                        boolean result = client.delete(key);
                        long i = count.incrementAndGet();
                        if (logger.isDebugEnabled()) {
                            logger.debug("[{}] Delete key[{}]: {}={}", inet, i, key, result);
                        }
                    }
                }
            } catch (MemcachedException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        });
        logger.info("Delete a total of {} keys starting with {}", count.get(), keyPrefix);
        return count.get();
    }

    @Deprecated
    public static List<String> getAllKey(String keyPrefix) {
        MemcachedClient client = getClient();
        List<String> keys = new ArrayList<>();
        client.getAvailableServers().forEach(inet -> {
            try {
                KeyIterator iterator = client.getKeyIterator(inet);
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    if (key.startsWith(keyPrefix)) {
                        keys.add(key);
                    }
                }
            } catch (MemcachedException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        });
        return keys;
    }

    /**
     * 动态添加一台服务
     * @param host
     * @param port
     * @return
     */
    public static boolean addServer(String host, int port) {
        return addServer(host, port, 1);
    }
    /**
     * 动态添加一台服务
     * @param host
     * @param port
     * @return
     */
    public static boolean addServer(String host, int port, int weight) {
        try {
           Memcached.getClient().addServer(host, port, weight);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}
