package com.tsi.api.server.mybatis;

import com.tsi.api.server.mybatis.vo.AbstractDbmsVo;
import com.tsi.api.server.mybatis.vo.AlarmConfigVo;
import com.tsi.api.server.mybatis.vo.AlarmOccrVo;
import com.tsi.api.server.repository.TsiAlarmManager;
import com.tsi.api.server.repository.TsiSystemStatusManager;
import com.tsi.api.server.vo.SystemStatusVo;
import com.tsi.api.server.vo.TsiAlarmConfigVo;
import com.tsi.app.common.app.AppUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Getter
@Setter
@Service
public class TsiDatabaseService {

    private TsiDatabaseMapper tsiDatabaseMapper;
    private TscSsipApiMapper tscSsipApiMapper;

    public TsiDatabaseService() {
    }

    @PostConstruct
    void init() {
        this.tsiDatabaseMapper = (TsiDatabaseMapper) AppUtils.getBean(TsiDatabaseMapper.class);
        this.tscSsipApiMapper = (TscSsipApiMapper) AppUtils.getBean(TscSsipApiMapper.class);
        initDatabase();
        loadDatabase();
    }

    public void initDatabase() {
    }

    public void loadDatabase() {
    }

    public int loadAlarmConfig() {
        //long startTime = System.nanoTime();

        List<AlarmConfigVo> objLists = this.tsiDatabaseMapper.getAlarmConfig();
        for (AlarmConfigVo obj : objLists) {
            TsiAlarmConfigVo alarm = TsiAlarmManager.getInstance().get(obj.getAlarmCode());
            if (alarm != null) {
                alarm.setDesc(obj.getDesc());
                alarm.setValue(obj.getValue());
                alarm.setUseYn(obj.getUseYn().equals("Y"));
            }
            else {
                alarm = new TsiAlarmConfigVo();
                alarm.setAlarmCode(obj.getAlarmCode());
                alarm.setDesc(obj.getDesc());
                alarm.setValue(obj.getValue());
                alarm.setUseYn(obj.getUseYn().equals("Y"));
                TsiAlarmManager.getInstance().put(obj.getAlarmCode(), alarm);
            }
        }
        //log.info("      loadAlarmConfig: {} EA, {} {}.", objLists.size(), TimeUtils.elapsedTime(startTime), Thread.currentThread().getName());
        return objLists.size();
    }

    public int insertAlarmOccrHs(AlarmOccrVo vo) {
        int res = 0;
        try {
            res = this.tsiDatabaseMapper.insertAlarmOccrHs(vo);
        }
        catch(Exception e) {
            log.error("{}", e.getMessage());
        }
        return res;
    }
    public int updateProcessState(int flag) {
        int res = 0;
        try {
            if (flag == 0) {
                res = this.tsiDatabaseMapper.updateProcessStatusStart(TsiAlarmManager.getInstance().getProcessStateVo());
            }
            else if (flag == 1) {
                res = this.tsiDatabaseMapper.updateProcessStatusRun(TsiAlarmManager.getInstance().getProcessStateVo());
            }
            else {
                res = this.tsiDatabaseMapper.updateProcessStatusStop(TsiAlarmManager.getInstance().getProcessStateVo());
            }
        }
        catch(Exception e) {
            log.error("{}", e.getMessage());
        }
        return res;
    }
    public int updateSystemStatus() {
        int job = 0;
        long currTm = System.currentTimeMillis();
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMddHHmmss");
        String clctDt = sdfDate.format(new Date());

        for (Map.Entry<String, SystemStatusVo> obj : TsiSystemStatusManager.getInstance().getMap().entrySet()) {
            SystemStatusVo status = obj.getValue();
            status.setClctDt(clctDt);
            if (status.isUpdate() || (currTm - status.getUpdateTm() <= 20000)) {
                // 최신이거나 최소 이전 주기 데이터까지 현재시점으로 업데이트 한다.
                try {
                    this.tscSsipApiMapper.insertSystemStatusHs(status);
                    job++;
                }
                catch(Exception e) {
                    log.error("{}", e.getMessage());
                }

                // 시스템 알람 발생 이력 저장 "SYS_01";     // 시스템 CPU 사용량(%)
                // 시스템 알람 발생 이력 저장 "SYS_02";     // 시스템 메모리 사용량(%)
                // 시스템 알람 발생 이력 저장 "SYS_03";     // 시스템 Disk 사용량(%)
                if (TsiAlarmManager.getInstance().checkAlarm(TsiAlarmConfigVo.SYS_01)) {
                    TsiAlarmConfigVo config1 = TsiAlarmManager.getInstance().get(TsiAlarmConfigVo.SYS_01);
                    if (status.getUseCpuRate() > config1.getValue()) {
                        AlarmOccrVo cpuAlarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
                        cpuAlarm.setAlarmCode(TsiAlarmConfigVo.SYS_01);
                        cpuAlarm.setAlarmTarget(status.getHostName());
                        cpuAlarm.setAlarmValue(Float.toString(status.getUseCpuRate()));
                        this.tsiDatabaseMapper.insertAlarmOccrHs(cpuAlarm);
                    }
                }
                if (TsiAlarmManager.getInstance().checkAlarm(TsiAlarmConfigVo.SYS_02)) {
                    TsiAlarmConfigVo config2 = TsiAlarmManager.getInstance().get(TsiAlarmConfigVo.SYS_02);
                    if (status.getUseMemRate() > config2.getValue()) {
                        AlarmOccrVo memAlarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
                        memAlarm.setAlarmCode(TsiAlarmConfigVo.SYS_02);
                        memAlarm.setAlarmTarget(status.getHostName());
                        memAlarm.setAlarmValue(Float.toString(status.getUseCpuRate()));
                        this.tsiDatabaseMapper.insertAlarmOccrHs(memAlarm);
                    }
                }
                if (TsiAlarmManager.getInstance().checkAlarm(TsiAlarmConfigVo.SYS_03)) {
                    TsiAlarmConfigVo config3 = TsiAlarmManager.getInstance().get(TsiAlarmConfigVo.SYS_03);
                    if (status.getUseDiskRate() > config3.getValue()) {
                        AlarmOccrVo memAlarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
                        memAlarm.setAlarmCode(TsiAlarmConfigVo.SYS_03);
                        memAlarm.setAlarmTarget(status.getHostName());
                        memAlarm.setAlarmValue(Float.toString(status.getUseCpuRate()));
                        this.tsiDatabaseMapper.insertAlarmOccrHs(memAlarm);
                    }
                }

            }
            status.setUpdate(false);
        }
        return job;
    }
}
