package com.sobot.network.http.upload;

import android.util.Log;

import com.sobot.network.http.model.SobotProgress;
import com.sobot.network.http.request.RequestCall;
import com.sobot.network.http.task.XExecutor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 全局的上传管理
 */
public class SobotUpload {
    private static SobotUpload instance;

    private Map<String, SobotUploadTask<?>> taskMap;         //所有任务
    private SobotUploadThreadPool threadPool;                //上传的线程池

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

    private SobotUpload() {
        threadPool = new SobotUploadThreadPool();
        taskMap = new LinkedHashMap<>();

        //校验数据的有效性，防止下载过程中退出，第二次进入的时候，由于状态没有更新导致的状态错误
        /*List<SobotProgress> taskList = UploadManager.getInstance().getUploading();
        for (Progress info : taskList) {
            if (info.status == Progress.WAITING || info.status == Progress.LOADING || info.status == Progress.PAUSE) {
                info.status = Progress.NONE;
            }
        }
        UploadManager.getInstance().replace(taskList);*/
    }

    public static <T> SobotUploadTask<T> request(String tag, RequestCall request) {
        Map<String, SobotUploadTask<?>> taskMap = SobotUpload.getInstance().getTaskMap();
        //noinspection unchecked
        SobotUploadTask<T> task = (SobotUploadTask<T>) taskMap.get(tag);
        if (task == null) {
            task = new SobotUploadTask<>(tag, request);
            taskMap.put(tag, task);
        }
        return task;
    }

    /** 从数据库中恢复任务 */
    public static <T> SobotUploadTask<T> restore(SobotProgress progress) {
        Map<String, SobotUploadTask<?>> taskMap = SobotUpload.getInstance().getTaskMap();
        //noinspection unchecked
        SobotUploadTask<T> task = (SobotUploadTask<T>) taskMap.get(progress.tag);
        if (task == null) {
            task = new SobotUploadTask<>(progress);
            taskMap.put(progress.tag, task);
        }
        return task;
    }

    /** 从数据库中恢复任务 */
    public static List<SobotUploadTask<?>> restore(List<SobotProgress> progressList) {
        Map<String, SobotUploadTask<?>> taskMap = SobotUpload.getInstance().getTaskMap();
        List<SobotUploadTask<?>> tasks = new ArrayList<>();
        for (SobotProgress progress : progressList) {
            SobotUploadTask<?> task = taskMap.get(progress.tag);
            if (task == null) {
                task = new SobotUploadTask<>(progress);
                taskMap.put(progress.tag, task);
            }
            tasks.add(task);
        }
        return tasks;
    }

    /** 开始所有任务 */
    public void startAll() {
        for (Map.Entry<String, SobotUploadTask<?>> entry : taskMap.entrySet()) {
            SobotUploadTask<?> task = entry.getValue();
            if (task == null) {
                Log.w("","can't find task with tag = " + entry.getKey());
                continue;
            }
            task.start();
        }
    }

    /** 暂停全部任务 */
    public void pauseAll() {
        //先停止未开始的任务
        for (Map.Entry<String, SobotUploadTask<?>> entry : taskMap.entrySet()) {
            SobotUploadTask<?> task = entry.getValue();
            if (task == null) {
                Log.w("","can't find task with tag = " + entry.getKey());
                continue;
            }
            if (task.progress.status != SobotProgress.LOADING) {
                task.pause();
            }
        }
        //再停止进行中的任务
        for (Map.Entry<String, SobotUploadTask<?>> entry : taskMap.entrySet()) {
            SobotUploadTask<?> task = entry.getValue();
            if (task == null) {
                Log.w("","can't find task with tag = " + entry.getKey());
                continue;
            }
            if (task.progress.status == SobotProgress.LOADING) {
                task.pause();
            }
        }
    }

    /** 删除所有任务 */
    public void removeAll() {
        Map<String, SobotUploadTask<?>> map = new HashMap<>(taskMap);
        //先删除未开始的任务
        for (Map.Entry<String, SobotUploadTask<?>> entry : map.entrySet()) {
            SobotUploadTask<?> task = entry.getValue();
            if (task == null) {
                Log.w("","can't find task with tag = " + entry.getKey());
                continue;
            }
            if (task.progress.status != SobotProgress.LOADING) {
                task.remove();
            }
        }
        //再删除进行中的任务
        for (Map.Entry<String, SobotUploadTask<?>> entry : map.entrySet()) {
            SobotUploadTask<?> task = entry.getValue();
            if (task == null) {
                Log.w("","can't find task with tag = " + entry.getKey());
                continue;
            }
            if (task.progress.status == SobotProgress.LOADING) {
                task.remove();
            }
        }
    }

    public SobotUploadThreadPool getThreadPool() {
        return threadPool;
    }

    public Map<String, SobotUploadTask<?>> getTaskMap() {
        return taskMap;
    }

    public SobotUploadTask<?> getTask(String tag) {
        return taskMap.get(tag);
    }

    public boolean hasTask(String tag) {
        return taskMap.containsKey(tag);
    }

    public SobotUploadTask<?> removeTask(String tag) {
        return taskMap.remove(tag);
    }

    public void addOnAllTaskEndListener(XExecutor.OnAllTaskEndListener listener) {
        threadPool.getExecutor().addOnAllTaskEndListener(listener);
    }

    public void removeOnAllTaskEndListener(XExecutor.OnAllTaskEndListener listener) {
        threadPool.getExecutor().removeOnAllTaskEndListener(listener);
    }

    public void unRegister() {
//        Map<String, SobotUploadTask<?>> taskMap = SobotUpload.getInstance().getTaskMap();
        for (SobotUploadTask task : this.taskMap.values()) {
            task.listeners.clear();
        }
    }
}
