package com.its.wthr.service;

import com.its.app.AppUtils;
import com.its.app.utils.SysUtils;
import com.its.wthr.config.ServerConfig;
import com.its.wthr.mapper.UnitSystMapper;
import com.its.wthr.process.AbstractDbmsJobProcess;
import com.its.wthr.process.DbmsJobData;
import com.its.wthr.process.DbmsJobType;
import com.its.wthr.vo.UnitSystSttsVo;
import com.its.wthr.vo.UnitSystVo;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Getter
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = {Exception.class})
public class UnitSystService {

    private String processId;
    private final UnitSystMapper unitSystMapper;

    private final UnitSystVo unitSyst = new UnitSystVo();
    private final UnitSystSttsVo unitSystStts = new UnitSystSttsVo();
    private final ConcurrentHashMap<String, UnitSystVo> unitSystMap = new ConcurrentHashMap<>();

    private int sttsMin;

    public static String _srcIpAddr;

    @PostConstruct
    private void init() {
        log.info("[LOADING...] UnitSystService.init: start.");
        ServerConfig serverConfig = (ServerConfig) AppUtils.getBean(ServerConfig.class);
        this.processId = serverConfig.getProcessId();

        try {
            InetAddress local = InetAddress.getLocalHost();
            String localIp = local.getHostAddress();
            long ipAddr = SysUtils.ipToLong(localIp);
            UnitSystService._srcIpAddr = String.format("%03d.%03d.%03d.%03d-", (ipAddr>>24)&0xFF, (ipAddr>>16)&0xFF, (ipAddr>>8)&0xFF, (ipAddr)&0xFF);
        } catch (UnknownHostException e) {
            UnitSystService._srcIpAddr = "127.000.000.001-";
            log.error("{}", e.getMessage());
        }

        log.info("[LOADING...] UnitSystService.init. _srcIpAddr: {}", UnitSystService._srcIpAddr);
        log.info("[LOADING...] UnitSystService.init. processId: {}", this.processId);
        log.info("[LOADING...] UnitSystService.init: ..end.");
    }

    @PreDestroy
    public void destroyService() {
        log.error("UnitSystService.destroy. system terminated.......");
        updateUnitSyst(false);
    }

    public void loadMaster() {
        try {
            // 초기화, 기존 정보 삭제로 초기화
            for (Map.Entry<String, UnitSystVo> e : this.unitSystMap.entrySet()) {
                e.getValue().setDEL_YN("Y");
            }

            List<UnitSystVo> systList = this.unitSystMapper.selectAll();
            log.info("[LOADING...] UnitSystService.selectAll(), {} EA", systList.size());
            for (UnitSystVo unit : systList) {
                if (unit.getSYST_ID().equals(this.processId)) {
                    this.unitSystStts.setSYST_ID(this.processId);
                    String localIp = unit.getSYST_IP_1().trim();
                    long ipAddr = SysUtils.ipToLong(localIp);
                    UnitSystService._srcIpAddr = String.format("%03d.%03d.%03d.%03d-", (ipAddr>>24)&0xFF, (ipAddr>>16)&0xFF, (ipAddr>>8)&0xFF, (ipAddr)&0xFF);
                    log.info("[LOADING...] UnitSystService.loadMaster: _srcIpAddr: {}", UnitSystService._srcIpAddr);
                }

                if (unit.getSYST_TYPE().contentEquals("UOT")) {
                    unit.setSYST_IP_1(unit.getSYST_IP_1().trim());
                    this.unitSystMap.put(unit.getSYST_ID(), unit);
                }
            }
        }
        catch (Exception e) {
            log.error("[LOADING...] UnitSystService.selectAll: Exception: {}", e.getMessage());
        }
        //for (Map.Entry<String, UnitSystVo> e : this.unitSystMap.entrySet()) {
        //    log.info(e.toString());
        //}
    }

    public void updateUnitSyst(boolean isRun) {
        boolean insHs = false;
        Calendar cal = Calendar.getInstance();
        int min = cal.get(Calendar.MINUTE);
        if ((min % 5) == 0) {
            insHs = true;
            this.sttsMin = min;
        }

        String SYST_STTS_CD = isRun ? "SPS1" : "SPC3";
        this.unitSystStts.setSYST_ID(this.processId);
        this.unitSystStts.setUPDT_DT(SysUtils.getSysTime());
        this.unitSystStts.setSYST_STTS_CD(SYST_STTS_CD);

        if (!isRun) {
            this.unitSystMapper.updateUnitSystStts(this.unitSystStts);
            if (insHs) {
                this.unitSystMapper.insertUnitSystSttsHs(this.unitSystStts);
            }
        }
        else {
            AbstractDbmsJobProcess.addQ(new DbmsJobData(DbmsJobType.DATA_TYPE_UNIT_SYST_STTS, insHs, this.unitSystStts, 1));
            if (insHs) {
                //loadMaster();
            }
        }
    }
}
