package com.maniu.http;

import android.util.Log;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 请求任务的管理对象
 * 请求任务队列
 */
public class ThreadManager {
    private static ThreadManager threadManager = new ThreadManager();
    //请求任务的队列
    private LinkedBlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<>();
    //线程池
    private ThreadPoolExecutor threadPoolExecutor;
    //请求重试队列
    private DelayQueue<HttpTask> faildQueue = new DelayQueue<>();



    private ThreadManager(){
        threadPoolExecutor = new ThreadPoolExecutor(3, 10, 15,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
                //当线程被拒绝或者因为其他原因失败了  就会被回调到这里
                mQueue.add(runnable);
            }
        });
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(failedRunable);
    }

    public static ThreadManager getInstance(){
        return threadManager;
    }


    public void addTask(Runnable runnable){
        if(runnable!=null){
            mQueue.add(runnable);
        }
    }


    /**
     * 将失败的请求线程加入到重试队列中
     * @param httpTask
     */
    public void addFailedTask(HttpTask httpTask){
        if(httpTask == null){
            return;
        }
        httpTask.setDelayTime(3000);
        faildQueue.offer(httpTask);
    }

    /**
     * 核心线程 它的工作是不断的去队列中拿到请求  然后交给线程池去执行
     */
    public Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true){
                try {
                    Runnable httpTask = mQueue.take();
                    threadPoolExecutor.execute(httpTask);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };


    /**
     * 重试队列的核心线程 不停的去重试队列中获取失败的请求去交给线程池执行
     */
    public Runnable failedRunable = new Runnable() {
        @Override
        public void run() {
            while (true){
                try {
                    HttpTask take = faildQueue.take();
                    if(take.getMaxFaildNum() <3 ){
                        take.setMaxFaildNum(take.getMaxFaildNum()+1);
                        threadPoolExecutor.execute(take);
                        Log.e("请求重试机制-----------","我是次数"+take.getMaxFaildNum());
                    }else{
                        //完全执行失败 这个时候就回调应用层  这个请求没救了
                        take.getiHttpRequest().getCallBackListenner().onFaild();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };
}
