package com.cretin.webservices.service.api.log

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.cretin.entity.common.CommonPageResp
import com.cretin.entity.log.*
import com.cretin.webcore.exception.WholeException
import com.cretin.webcore.oss.QiniuAuthHelper
import com.cretin.webcore.utils.getFileName
import com.cretin.webcore.utils.toStandTime
import com.cretin.webdb.entity.TbLogcatDeviceItem
import com.cretin.webdb.entity.TbLogcatStringItem
import com.cretin.webdb.service.ITbLogcatDeviceItemService
import com.cretin.webdb.service.ITbLogcatStringItemService
import com.cretin.webredis.RedisUtils
import org.apache.http.util.TextUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.util.concurrent.TimeUnit
import javax.servlet.http.HttpServletRequest

@Service
class LogService {

    @Autowired
    private var tbLogcatStringItemService: ITbLogcatStringItemService? = null


    @Autowired
    private var tbLogcatDeviceItemService: ITbLogcatDeviceItemService? = null

    @Autowired
    private var redisUtils: RedisUtils? = null

    /**
     * 添加logcat
     */
    fun addLogcat(data: AddLogcatReq, httpServletRequest: HttpServletRequest): Any {
        tbLogcatStringItemService?.save(TbLogcatStringItem().apply {
            this.logUrl = data.url
            this.addTime = LocalDateTime.now()
            this.mac = data.mac.toUpperCase()
            this.size = data.size
        })
        return "ok"
    }

    fun logcatList(data: LogcatListReq, httpServletRequest: HttpServletRequest): Any {
        val result = mutableListOf<MutableMap<String, String>>()
        tbLogcatStringItemService?.list(QueryWrapper<TbLogcatStringItem>().apply {
            if (!TextUtils.isEmpty(data.mac)) {
                this.like("mac", data.mac.toUpperCase())
            }
            this.orderByDesc("id")
        })?.forEach {
            result.add(
                mutableMapOf(
                    "filename" to it.logUrl.getFileName(),
                    "time" to it.addTime.toStandTime(),
                    "id" to it.id.toString(),
                    "url" to (QiniuAuthHelper.urlGet(it.logUrl) ?: ""),
                    "mac" to it.mac,
                    "size" to (it.size ?: "")
                )
            )
        }
        return result
    }

    fun logcatDetails(data: LogcatDetailsReq, httpServletRequest: HttpServletRequest): Any {
        val item = tbLogcatStringItemService?.getById(data.id) ?: throw WholeException("日志不存在或被删除")
        return mutableMapOf(
            "url" to QiniuAuthHelper.urlGet(item.logUrl),
        )
    }

    fun addDeviceInfo(data: AddDeviceReq, httpServletRequest: HttpServletRequest) {
        val tbLogcatDeviceItem = tbLogcatDeviceItemService?.getOne(QueryWrapper<TbLogcatDeviceItem>().apply {
            this.eq("mac", data.mac)
        }, false)
        if (tbLogcatDeviceItem != null) {
            tbLogcatDeviceItem.logcatFilter = data.log_filter
            tbLogcatDeviceItem.autologFlag = if (data.auto_flag) 1 else 0
            tbLogcatDeviceItem.openFlag = if (data.open_flag) 1 else 0
            tbLogcatDeviceItem.currentStatus = 0
            tbLogcatDeviceItem.heartbeatInterval = data.time_interval
            tbLogcatDeviceItemService?.updateById(tbLogcatDeviceItem)
        } else {
            val tbLogcatDeviceItem = TbLogcatDeviceItem()
            tbLogcatDeviceItem.addTime = LocalDateTime.now()
            tbLogcatDeviceItem.mac = data.mac
            tbLogcatDeviceItem.logcatFilter = data.log_filter
            tbLogcatDeviceItem.autologFlag = if (data.auto_flag) 1 else 0
            tbLogcatDeviceItem.openFlag = if (data.open_flag) 1 else 0
            tbLogcatDeviceItem.currentStatus = 0
            tbLogcatDeviceItem.heartbeatInterval = data.time_interval
            tbLogcatDeviceItemService?.save(tbLogcatDeviceItem)
        }
    }

    fun deviceList(data: DeviceListReq, httpServletRequest: HttpServletRequest): Any {
        val items = mutableListOf<MutableMap<String, Any>>()
        val page = Page<TbLogcatDeviceItem>(data.page, data.size)
        tbLogcatDeviceItemService?.page(page, QueryWrapper<TbLogcatDeviceItem>().apply {
            if (!TextUtils.isEmpty(data.mac)) {
                this.like("mac", data.mac)
            }
            this.orderByDesc("id")
        })?.records?.forEach {
            val redisStatus = redisUtils?.get("device_logcat_status_" + it.mac)
            var currentStatus = it.currentStatus
            if (!TextUtils.isEmpty(redisStatus)) {
                currentStatus = redisStatus?.toInt() ?: 0
            }
            items.add(
                mutableMapOf(
                    "id" to it.id,
                    "mac" to it.mac,
                    "addTime" to it.addTime.toStandTime(),
                    "openFlag" to (it.openFlag == 1),
                    "timeInterval" to it.heartbeatInterval,
                    "autoLog" to it.autologFlag,
                    "logcatFilter" to it.logcatFilter,
                    "currentStatusFlag" to currentStatus,
                    "currentStatus" to when (currentStatus) {
                        //0 未启动 1 抓取中 2 已完成
                        0 -> {
                            "未启动"
                        }

                        1 -> {
                            "抓取中"
                        }

                        else -> {
                            "已完成"
                        }
                    }
                )
            )
        }
        return CommonPageResp(page.total.toInt(), data.page.toInt(), data.size.toInt(), items, null)
    }

    fun getDeviceInfo(data: DeviceConfigReq, httpServletRequest: HttpServletRequest): Any {
        val it = tbLogcatDeviceItemService?.getOne(QueryWrapper<TbLogcatDeviceItem>().apply {
            this.eq("mac", data.mac)
        }, false) ?: throw WholeException("未配置服务")
        return mutableMapOf(
            "id" to it.id,
            "mac" to it.mac,
            "addTime" to it.addTime.toStandTime(),
            "openFlag" to (it.openFlag == 1),
            "timeInterval" to it.heartbeatInterval,
            "autoLog" to it.autologFlag,
            "logcatFilter" to it.logcatFilter
        )
    }

    fun updateDeviceStatus(data: DeviceStatusReq, httpServletRequest: HttpServletRequest): Any {
        //当前日志状态  0 未启动 1 抓取中 2 已完成
        if (data.status == 2 || data.status == 0) {
            val it = tbLogcatDeviceItemService?.getOne(QueryWrapper<TbLogcatDeviceItem>().apply {
                this.eq("mac", data.mac)
            }, false) ?: throw WholeException("未配置服务")
            it.currentStatus = data.status
            tbLogcatDeviceItemService?.updateById(it)
        }
        val forceStop = redisUtils?.get("device_logcat_status_force_stop_"+data.mac)
        if (data.status != 2)
            redisUtils?.setEx("device_logcat_status_" + data.mac, data.status.toString(), 5, TimeUnit.MINUTES)
        else {
            redisUtils?.delete("device_logcat_status_" + data.mac)
            redisUtils?.delete("device_logcat_status_force_stop_" + data.mac)
        }
        return mutableMapOf(
            "status" to (if(forceStop == "4") "force-stop" else "ok")
        )
    }

    fun deviceForceStop(data: DeviceForceStopReq, httpServletRequest: HttpServletRequest) {
        redisUtils?.setEx("device_logcat_status_force_stop_" + data.mac, "4", 5, TimeUnit.MINUTES)
    }

}