package cn.sagacloud.server.scheduler.service

import cn.sagacloud.server.DispatchTask
import cn.sagacloud.server.scheduler.models.DownloadEntity
import cn.sagacloud.server.scheduler.models.TaskEntity
import cn.sagacloud.server.scheduler.models.TaskResultEntity
import com.sybotan.database.SFilter
import com.sybotan.database.enums.SDirection
import com.sybotan.mybatis.SMybatisDao
import com.sybotan.service.SObjectService
import com.sybotan.service.models.enums.SResponseType
import com.sybotan.service.models.requests.SCreateRequest
import com.sybotan.service.models.requests.SUpdateRequest
import org.springframework.stereotype.Component
import java.util.stream.Collectors

@Component
class TasksService{

    /**
     * 根据任务的状态获取任务(包含下载子任务)
     */
    fun getAllTaskMapByStatus(statusList : List<Int>) : Map<String, TaskEntity> {
        // 获取所有任务 by status
        val tasks = BaseDataService.taskService.select(SFilter.inList("status", statusList)).order("createTime", SDirection.ASC) .exec()
        // 获取id List
//        val idList = tasks.stream().map{ task -> task.id }.distinct().collect(Collectors.toList())
        val idList = ArrayList<String>()
        tasks.stream().forEach { task -> if(!idList.contains(task.id!!))idList.add(task.id!!) }
        // 变成map
        val taskMap = HashMap<String, TaskEntity>()
        tasks.stream().forEach { task -> taskMap.put(task.id!!, task) }
        if(taskMap.size == 0)
            return taskMap
        // 获取它们的下载子任务
        val downloads = BaseDataService.downloadService.select(SFilter.inList("taskId", idList)).exec()
        // 填充下载子任务到任务里
        downloads.stream().forEach { download ->
            if(taskMap[download.taskId] != null)
                taskMap[download.taskId]!!.downloadTaskList.add(download)
        }
        val iterator = taskMap.iterator()
        while(iterator.hasNext()){
            val next = iterator.next()
            if(next.value.downloadTaskList.isEmpty()){
                iterator.remove()
            }
        }
        return taskMap
    }

    /**
     * 更新一个task任务
     */
    fun updateTask(taskEntity: TaskEntity) : Boolean{
        val update = SUpdateRequest<TaskEntity>()
        val list = ArrayList<TaskEntity>()
        list.add(taskEntity)
        update.content = list
        try {
            // 先更新taskEntity
            BaseDataService.taskService.updateList(update)
            // 删除 所有 download 表里 taskId = taskEntity.id的行
            BaseDataService.downloadService.delete(SFilter.eq("taskId", taskEntity.id!!))
            // 添加 taskEntity的downloadTaskList到download表.
            val request = SCreateRequest<DownloadEntity>()
            request.content = taskEntity.downloadTaskList
            BaseDataService.downloadService.createList(request)
            return true
        }catch (e: Exception) {
            e.printStackTrace()
            return false
        }
    }


    /**
     * 更新一个task任务
     */
    fun updateSingleTask(taskEntity: TaskEntity) : Boolean{
        val update = SUpdateRequest<TaskEntity>()
        val list = ArrayList<TaskEntity>()

        try {
            list.add(taskEntity)
            update.content = list
            BaseDataService.taskService.updateList(update)
            DispatchTask.syncTask()
            return true
        }catch (e: Exception) {
            e.printStackTrace()
            return false
        }
    }

    /**
     * 添加一个TaskResult对象到数据库
     */
    fun createTaskResult(taskResult: TaskResultEntity): Boolean {
        val create = SCreateRequest<TaskResultEntity>()
        create.content = arrayListOf(taskResult)
        return BaseDataService.taskResultService.createList(create).result == SResponseType.success
    }

    /**
     * 根据下载文件的MD5值来匹配taskMap中的任务
     */
    fun getTaskByMD5(md5List : ArrayList<String>, taskMap : Map<String, TaskEntity>) : TaskEntity?{
        if(md5List.isEmpty())
            return null
        val md5Map = HashSet<String>(md5List)
        for (t in taskMap){
            for(down in t.value.downloadTaskList){
                if (md5Map.contains(down.md5!!.toLowerCase()) || md5Map.contains(down.md5!!.toUpperCase())) {
                    return t.value
                }
            }
        }
        return null
    }
//    /**
//     * 更新一个task任务
//     */
//    fun updateTaskByAttr(taskEntity: TaskEntity, updateKeys : ArrayList<TaskEntityAttr>) : Boolean{
//        val update = SUpdateRequest<TaskEntity>()
//        val list = ArrayList<TaskEntity>()
//
//        try {
//            val singleTask = setUpdateKeys(taskEntity, updateKeys)
//            list.add(singleTask)
//            update.content = list
//            taskService.updateList(update)
//
//            return true
//        }catch (e: Exception) {
//            e.printStackTrace()
//            return false
//        }
//    }

//    private fun setUpdateKeys(taskEntity: TaskEntity, updateKeys: java.util.ArrayList<TaskEntityAttr>) : TaskEntity{
//
//    }
}