package com.base.task;

import com.base.task.core.Execute;
import com.base.task.core.TaskCache;
import com.base.task.core.TaskThread;
import com.base.task.core.listener.FileMonitor;
import com.base.task.handler.TaskHandler;
import com.base.task.model.Enums.TaskTypeEnum;
import com.base.task.model.Mapping;
import com.base.task.model.TaskPreparations;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
@Component
@Slf4j
@ConfigurationProperties(prefix = "exe")
public class TaskInitialize implements InitializingBean {


    public Map<String,  List<String>> FilepathMap = new HashMap<>();

    public Map<TaskTypeEnum, TaskHandler> map = new HashMap<>();
    @Resource
    List<TaskHandler> taskHandlerList;

    @Resource
    Execute execute;

    @Resource
    TaskPreparations taskPreparations;
    //线程启动
    @Override
    public void afterPropertiesSet() {
        if (!formatHandler()){
            return;
        }
        //线程启动
        startCheckThread();
        startTaskThread();
        FileMonitor.getInstance().monitorStart();

    }

    private Boolean formatHandler() {
        //业务调用赋值
        if (CollectionUtils.isEmpty(taskHandlerList)) {
            log.error("task nothing to do");
            return Boolean.FALSE;
        }
        for (TaskHandler taskHandler : taskHandlerList) {
            Class<?> beanClazz = taskHandler.getClass();
            Mapping annotation = beanClazz.getAnnotation(Mapping.class);
            if (annotation == null) {
                log.error("taskHandler {} not found mapping", beanClazz);
            }
            assert annotation != null;
            TaskTypeEnum taskTypeEnum = annotation.taskTypeEnum();
            map.put(taskTypeEnum, taskHandler);
        }
        return Boolean.TRUE;
    }

    private void startCheckThread() {
        Runnable checkRunnable = () -> {
            try {
                while (true) {
                    Thread.sleep(3000);
                    execute.checkExecuteQueue();
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

        };
        Thread thread = new Thread(checkRunnable);
        thread.setName("taskCheck");
        thread.start();
        log.info(thread.getName() + " starting!!!");
    }

    private void startTaskThread() {
        TaskCache taskCache = TaskCache.getInstance();
        //初始化当前任务集合
        taskCache.initCurrentTaskMap(taskPreparations);
        //添加线程监控（根据设置的任务最大个数：type * taskPreparations.getExePackageCounts()）
        TaskTypeEnum[] taskTypeEnums = TaskTypeEnum.values();
        for (TaskTypeEnum taskTypeEnum : taskTypeEnums) {
            TaskThread thread = new TaskThread(taskTypeEnum, execute);
            Thread thread1 = new Thread(thread);
            thread1.setName(taskTypeEnum.toString());
            execute.addThread(taskTypeEnum, thread1);
        }
        execute.start();
    }

}

