/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .F88X
 *        X8888Y
 *      .}888888N;
 *        i888888N;        .:!              .I$WI:
 *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
 *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
 *            +888888N;  .8888888Y                                  "&&8Y.}8,
 *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
 *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
 *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
 *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
 *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
 *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
 *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
 *      .:R888888I
 *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
 *        ~8888'
 *        .!88~                                                                     All rights reserved.
 *
 * *********************************************************************************************************************
 */

package com.persagy.server.scheduler.service

import com.persagy.database.SFilter
import com.persagy.database.enums.SDirection
import com.persagy.server.scheduler.models.DownloadEntity
import com.persagy.server.scheduler.models.TaskEntity
import com.persagy.server.scheduler.models.TaskResultEntity
import com.persagy.server.scheduler.server.DispatchTask
import com.persagy.service.models.enums.SResponseType
import com.persagy.service.models.requests.SCreateRequest
import com.persagy.service.models.requests.SUpdateRequest
import org.springframework.stereotype.Component

@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{
//
//    }
}