package cn.estsh.i3plus.core.apiservice.controller.busi;

import cn.estsh.i3plus.core.api.iservice.busi.ISysDashboardService;
import cn.estsh.i3plus.platform.common.tool.SerializeTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.annotation.AnnoIgnoreLog;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.exception.ImppExceptionEnum;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.ResultBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description : Dashboard服务
 * @Reference :
 * @Author : yunhao
 * @CreateDate : 2018-12-10 17:04
 * @Modify:
 **/
@RestController
@Api(description = "Dashboard服务")
@RequestMapping(PlatformConstWords.BASE_URL + "/dashboard")
public class SysDashboardController extends CoreBaseController {
    private static final Logger LOGGER = LoggerFactory.getLogger(SysDashboardController.class);

    @Autowired
    private ISysDashboardService sysDashboardService;

    @Resource(name = "imppSessionManager")
    private DefaultWebSessionManager webSessionManager;

    @Resource(name = "redisCore")
    private ImppRedis redisCore;

    @AnnoIgnoreLog
    @GetMapping("/get-basic")
    @ApiOperation(value = "获取基础数据", notes = "获取基础数据，用户，部门，组织等信息")
    public ResultBean getBasicInfo() {
        try {
            LOGGER.info("getBasicInfo:{}",redisCore);
            // 保持时间,key统一
            String redisKey = PlatformConstWords.REDIS_DASHBOARD_BASIC_INFO + "_" + TimeTool.getNowTime("yyyyMMddhhmmss");

            Map<Object, Object> dashboardData = redisCore.getHashMap(redisKey);
            LOGGER.info("getBasicInforedisKey:{},dashboardData:{}",redisKey,dashboardData);
            if (dashboardData == null || dashboardData.size() == 0) {
                dashboardData = new HashMap<>();
                dashboardData.put("orgNum", sysDashboardService.getSysOrganizeCount());
                dashboardData.put("deptNum", sysDashboardService.getSysDepartmentCount());
                dashboardData.put("onlineUser", webSessionManager.getSessionDAO().getActiveSessions().size());
                dashboardData.put("userLoginLog", sysDashboardService.findSysUserLoginLog(10));

                redisCore.putHashMap(redisKey, dashboardData, 500);
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultMap(dashboardData);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @AnnoIgnoreLog
    @GetMapping(value = "/get-log")
    @ApiOperation(value = "查询日志", notes = "最近操作，异常日志")
    public ResultBean getLogInfo() {
        try {
            LOGGER.info("getLogInfo:{}",redisCore);
            // 保持时间,key统一
            String redisKey = PlatformConstWords.REDIS_DASHBOARD_LOG_INFO + "_" + TimeTool.getNowTime("yyyyMMddhhmmss");

            Map<Object, Object> dashboardData = redisCore.getHashMap(redisKey);
            LOGGER.info("getLogInforedisKey:{},dashboardData:{}",redisKey,dashboardData);
            if (dashboardData == null || dashboardData.size() == 0) {
                dashboardData = new HashMap<>();
                dashboardData.put("logOperate", sysDashboardService.findNewSysLogOperateSize(10));
                dashboardData.put("logException", sysDashboardService.findNewSysLogExceptionSize(10));

                redisCore.putHashMap(redisKey, dashboardData, 500);
            }

            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultMap(dashboardData);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @AnnoIgnoreLog
    @GetMapping(value = "/get-avg-response-time")
    @ApiOperation(value = "获取平均响应时间", notes = "获取平均响应时间")
    public ResultBean getAvgResponseTime() {
        LOGGER.info("getAvgResponseTime:{}",redisCore);
        try {
            // 保持时间,key统一
            String redisKey = PlatformConstWords.REDIS_DASHBOARD_AVG_RESP_TIME + "_" + TimeTool.getNowTime("yyyyMMddhhmmss");

            Map<Object, Object> dashboardData = redisCore.getHashMap(redisKey);
            LOGGER.info("getAvgResponseTimeredisKey:{},dashboardData:{}",redisKey,dashboardData);
            if (dashboardData == null || dashboardData.size() == 0) {
                // 获取前5分钟时间
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                Date nowDate = new Date();
                dashboardData = sysDashboardService.querySysLogSystemAvgExecuteTime(
                        sdf.format(TimeTool.timeCalc(nowDate, Calendar.MINUTE, -3)),sdf.format(nowDate));

                redisCore.putHashMap(redisKey, dashboardData, 500);
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultMap(dashboardData);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @AnnoIgnoreLog
    @GetMapping(value = "/get-level-log-num")
    @ApiOperation(value = "获取各等级日志数量", notes = "获取各等级日志数量")
    public ResultBean getLevelLogNum() {
        LOGGER.info("getLevelLogNum:{}",redisCore);
        try {
            // 保持时间,key统一
            String redisKey = PlatformConstWords.REDIS_DASHBOARD_LOG_NUM + "_" + TimeTool.getNowTime("yyyyMMddhhmms");

            Map<Object, Object> dashboardData = redisCore.getHashMap(redisKey);
            LOGGER.info("getLevelLogNumredisKey:{},dashboardData:{}",redisKey,dashboardData);
            if (dashboardData == null || dashboardData.size() == 0) {
                // 获取前10分钟时间，日志数量
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                Date nowDate = new Date();
                dashboardData = sysDashboardService.querySysLogSystemByLevel(
                                    sdf.format(TimeTool.timeCalc(nowDate, Calendar.MINUTE, -10)), sdf.format(nowDate));

                redisCore.putHashMap(redisKey, dashboardData, 500);
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultMap(dashboardData);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @AnnoIgnoreLog
    @GetMapping(value = "/get-server-pressure")
    @ApiOperation(value = "获取服务压力情况", notes = "获取服务压力情况")
    public ResultBean getServerPressure() {
        LOGGER.info("getServerPressure:{}",redisCore);
        try {
            // 保持时间,key统一
            String redisKey = PlatformConstWords.REDIS_DASHBOARD_SERVER_PRESSURE + "_" + TimeTool.getNowTime("yyyyMMddhhmmss");

            Map<Object, Object> dashboardData = redisCore.getHashMap(redisKey);
            LOGGER.info("getServerPressureredisKey:{},dashboardData:{}",redisKey,dashboardData);
            if (dashboardData == null || dashboardData.size() == 0) {
                dashboardData = new HashMap<>();
                //获取上一分钟,请求来源数据
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");

                Date nowDate = new Date();
                Map<?,?> dataMap = redisCore.getHashMap(
                        CommonConstWords.REDIS_DASHBOARD_MINUTE_SOURCE + "_" + sdf.format(TimeTool.timeCalc(nowDate, Calendar.MINUTE, -1)));
                if(dataMap == null){
                    dataMap = new HashMap<>();
                }
                dashboardData.put("requestSource", dataMap);

                //获取上一秒，服务器压力数据
                sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                Object pressureObj = redisCore.getObject(
                        CommonConstWords.REDIS_DASHBOARD_SECOND_PRESSURE + "_" + sdf.format(TimeTool.timeCalc(nowDate, Calendar.SECOND, -1)));
                int pressure = 0;
                if(pressureObj != null){
                    try {
                        pressure = Integer.parseInt(pressureObj.toString());
                    }catch (Exception e){
                        LOGGER.error("【无法转换压力】data：{}",pressureObj);
                    }
                }
                dashboardData.put("serverPressure", pressure);

                redisCore.putHashMap(redisKey, dashboardData, 500);
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultMap(dashboardData);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }
}
