package com.its.vms.service;

import com.its.app.utils.Elapsed;
import com.its.vms.dao.mapper.VmsAtmpMapper;
import com.its.vms.dto.TbVmsAtmpDto;
import com.its.vms.entity.TbVmsAtmp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
@RequiredArgsConstructor
public class VmsAtmpService {

    private final VmsAtmpMapper mapper;

    private final ConcurrentHashMap<Long, TbVmsAtmpDto> dataMap = new ConcurrentHashMap<>();

    public TbVmsAtmpDto find(Long atmpSttnNmbr) {
        return this.dataMap.get(atmpSttnNmbr);
    }

    public void loadDb() {
        loadVmsAtmpInfo();
    }

    public void loadVmsAtmpInfo() {
        Elapsed elapsed = new Elapsed();
        AtomicInteger nFailed = new AtomicInteger();
        AtomicInteger nSuccess = new AtomicInteger();
        try {
            List<TbVmsAtmp> infoList  = this.mapper.selectVmsAtmpInfo();
            log.info("VmsAtmpService.loadVmsAtmpInfo: {} EA", infoList.size());
            infoList.forEach(data -> {
                TbVmsAtmpDto dto = data.toDto();
                this.dataMap.put(dto.getAtmpSttnNmbr(), dto);
                if (dto.getMsrmDt() == null) {
                    dto.setSuccess(false);
                    nFailed.getAndIncrement();
                    return;
                }
                if ("0".equals(dto.getPm101hhGrad()) &&
                    "0".equals(dto.getPm251hhGrad()) &&
                    "0".equals(dto.getIntgAtmpGrad())) {
                    dto.setSuccess(false);
                    nFailed.getAndIncrement();
                    return;
                }
                dto.setSuccess(true);
                nSuccess.getAndIncrement();
            });
        }
        catch (Exception e) {
            log.error("VmsAtmpService.loadVmsAtmpInfo: {}.", e.toString());
        }

        if (nFailed.intValue() > 0 && nSuccess.intValue() > 0) {
            // 성공 데이터가 존재하고 실패 데이터가 존재하는 경우 데이터 보정
            correctVmsAtmpInfo();
        }
        log.info("VmsAtmpService.loadVmsAtmpInfo: {} ms.", elapsed.milliSeconds());
    }

    public void correctVmsAtmpInfo() {
        /**
         * 측정 데이터가 없는 경우 정상적인 측정 데이터를 가지고 보정한다.
         */
        TbVmsAtmpDto vmsAtmp = null;
        for (Map.Entry<Long, TbVmsAtmpDto > obj : this.dataMap.entrySet()) {
            if (obj.getValue().isSuccess()) {
                vmsAtmp = obj.getValue();
                break;
            }
        }
        if (vmsAtmp == null) {
            return;
        }
        for (Map.Entry<Long, TbVmsAtmpDto > obj : this.dataMap.entrySet()) {
            if (!obj.getValue().isSuccess()) {
                vmsAtmp.correct(obj.getValue());
            }
        }
    }
}
