package com.persagy.revit.backstage.state

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.persagy.database.SFilter
import com.persagy.revit.backstage.request.task.TaskCmd
import com.persagy.revit.models.message.MessageEntity
import com.persagy.revit.models.modelFile.ModelFile
import com.persagy.revit.models.modelFile.TaskEntity
import com.persagy.revit.services.BaseDataService
import com.persagy.revit.services.CommonService
import com.persagy.revit.services.message.MessageService
import com.persagy.revit.services.modelCheck.TaskService
import com.persagy.revit.services.monitor.ModelMonitorService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
 *
 *
 * @author jxing
 */
@Component
class DataExportState_20 : ModelState {
    companion object {
        // 日志
        private val logger = LoggerFactory.getLogger(DataExportState_20::class.java)
    } // Companion object

    val dataService = BaseDataService
    @Autowired
    lateinit var taskService: TaskService

    @Autowired
    lateinit var messageService: MessageService

    @Autowired
    lateinit var monitorService: ModelMonitorService

    var modelList: ArrayList<ModelFile>? = null

    /**
     * 准备数据
     */
    override fun prepareModel() {
        modelList = dataService.modelFileService.select(SFilter.eq("status", 20), SFilter.eq("removed", false)).exec()
    }

    /**
     * 检查模型在revit调度器中执行状态
     */
    override fun handle() {
        try {
            if (modelList.isNullOrEmpty()) {
                return
            }
            val taskList = taskService.queryTask(modelList!!, TaskCmd.DataExport)
            if (taskList == null) {
                logger.warn("状态20处理失败!")
                return
            }
            //val map = composeModelIdTaskIdMap(modelList!!, taskList)
            var map = HashMap<String, TaskEntity>() // <modelId, taskStatus>
            val updateList = ArrayList<ModelFile>()
            taskList.forEach {
                if (it.modelId != null && it.status != null)
                    map[it.modelId!!] = it
            }
            modelList!!.forEach {
                try {
                    if (!map.containsKey(it.id)) {
                        return@forEach
                    }
                    // 0 Waiting, 1 Sending, 2 Sent, 3 FileDownloadException, 4 CommandExecuteException, 5 Finished
                    // 获取楼层
                    val floorList = dataService.floorModelService.select(SFilter.eq("id", it.floorModelId!!)).exec()
                    val floor = floorList[0]
                    val task = map[it.id]
                    it.taskInfo!!.exportTask = task
                    val exportTime = Date()
                    when (task!!.status) {
                        2 -> {
                            //monitorService.beginExport(it.id!!, exportTime)
                        }
                        3 -> {
                            // 失败
                            val error = JSONObject()
                            error["Result"] = "Failure"
                            error["ResultMsg"] = "文件下载失败"
                            it.taskInfo!!.exportTask!!.resultJson = error.toString()
                            it.status = 21
                            updateList.add(it)
                        }
                        4 -> {
                            // 失败
                            val error = JSONObject()
                            error["Result"] = "Failure"
                            error["ResultMsg"] = "命令执行异常"
                            it.taskInfo!!.exportTask!!.resultJson = error.toString()
                            it.status = 21
                            updateList.add(it)
                        }
                        5 -> {
                            // 完成
                            val str = task.resultJson
                            var json = JSON.parseObject(str)
                            if (json == null) {
                                json = JSONObject()
                                json["info"] = str
                                it.status = 21
                            } else {
                                if ("success".equals(json["Result"] as String?, ignoreCase = true)) {
                                    it.status = 3
                                } else {
                                    it.status = 21
                                }
                            }
                            updateList.add(it)
                        }
                        else -> {
                        }   // task未完成, 进行中
                    }
                    val folderFloorName = CommonService.getReportPrefix(floor)
                    val message: MessageEntity
                    if (it.status == 21) {
                        // 发送检查通过通知
                        message = messageService.buildExportErrorMessage(it.projectId, it.userId ?: "",
                                "${folderFloorName.first}的${folderFloorName.second}模型上传失败，请重新上传", "模型导出数据失败: ${it.taskInfo!!.exportTask!!.resultJson}, 请联系开发人员")
                        dataService.modelFileService.update(it, UploadedState_1.projection)
                        monitorService.endExport(it.id!!, exportTime)
                        monitorService.modelExport(it.id!!, it.taskInfo!!.exportTask!!.resultJson, true)
                        messageService.sendMessage(message)
                    } else if (it.status == 3) {
                        message = messageService.buildRefreshMessage(it.projectId, it.userId ?: "")
                        dataService.modelFileService.update(it, UploadedState_1.projection)
                        monitorService.endExport(it.id!!, exportTime)
                        monitorService.modelExport(it.id!!)
                        messageService.sendMessage(message)
                    }
                } catch (e: Exception) {
                    monitorService.modelExport(it.id!!, e.message + CommonService.getStackTrace(e), false)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            logger.error(e.message)
        }
    }
}