package com.wuban.tron.explore.fetch;

import com.wuban.tron.explore.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author sky
 *
 */
@Slf4j
public class PersistThreadPoolV2 {

    private static final int POLL_SIZE = 1;

    private static PersistThreadPoolV2 instance;
    public final List<ThreadPoolExecutor> executors = new ArrayList<>(POLL_SIZE);

    private PersistThreadPoolV2() {
        for (int i = 0; i < POLL_SIZE; i++) {
            executors.add(new ThreadPoolExecutor(POLL_SIZE * 3, POLL_SIZE * 5, 30L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(), new PersistThreadFactory(i)));
        }
        log.info("数据持久化-线程池 name:{} coreSize:{} maxSize:{}", "PersistThreadPool", POLL_SIZE * 3, POLL_SIZE * 5);
    }

    public static PersistThreadPoolV2 getInstance() {
       if (instance == null) {
          synchronized (PersistThreadPoolV2.class) {
              if (instance == null) {
                  instance = new PersistThreadPoolV2();
              }
          }
       }

       return instance;
    }

    public void stop() {
        for (final ThreadPoolExecutor executor : executors) {
            ThreadPoolUtil.ensureShutdown(executor);
        }
    }

    public ThreadPoolExecutor getPool() {
        Random random = new Random();
        int index = random.nextInt(POLL_SIZE);
        return executors.get(index);
    }

    /**
     * The persist thread factory
     */
    static class PersistThreadFactory implements ThreadFactory {
        private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        PersistThreadFactory(final int index) {
            final SecurityManager s = System.getSecurityManager();
            this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            this.namePrefix = "persist-pool" + index + "-" + POOL_NUMBER.getAndIncrement() + "-thread-";
        }

        @Override
        public Thread newThread(final Runnable r) {
            final Thread t = new Thread(this.group, r,this.namePrefix + this.threadNumber.getAndIncrement(),0);
            if (t.isDaemon()) { t.setDaemon(false); }
            if (t.getPriority() != Thread.NORM_PRIORITY) { t.setPriority(Thread.NORM_PRIORITY); }
            return t;
        }
    }


}
