package com.its.dsrc.service;

import com.its.app.AppUtils;
import com.its.dsrc.dao.mapper.RseOffrSectMapper;
import com.its.dsrc.entity.TbRseCtlr;
import com.its.dsrc.entity.TbRseOffrSect;
import com.its.dsrc.entity.TbRseOffrSectTraf;
import com.its.dsrc.global.AppRepository;
import com.its.dsrc.vo.voDsrcOffrSectTraf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@Transactional(rollbackFor = {Exception.class})
public class MultimediaService {

    private RseOffrSectMapper rseOffrSectMapper;

    private ConcurrentHashMap<String, TbRseOffrSect> offrSectInfoMap = null;
    private ConcurrentHashMap<String, voDsrcOffrSectTraf> offrSectTrafMap = null;
    private List<TbRseOffrSectTraf> offrInfrHsList = null;

    @PostConstruct
    private void init() {
        log.info("MultimediaService.init: Start.");
        this.rseOffrSectMapper = (RseOffrSectMapper) AppUtils.getBean(RseOffrSectMapper.class);
        this.offrSectInfoMap = new ConcurrentHashMap<String, TbRseOffrSect>();
        this.offrSectTrafMap = new ConcurrentHashMap<String, voDsrcOffrSectTraf>();
        this.offrInfrHsList = Collections.synchronizedList(new ArrayList<>());

        //loadMaster();
        log.info("MultimediaService.init: ..End.");
    }

    public void loadMaster() {
        // DSRC 정보제공구간 목록 조회
        loadOffrSectInfo();

        // DSRC 정보제공구간 소통정보 조회
        // DSRC 제공구간정보에 포함된 기본정보를 소통정보 조회하면서 함께 조회하기 때문에
        // DSRC 정보제공구간정보는 조회하지 않는다.
        loadOffrSectTraf();
    }

    /*
     *  DSRC 제공구간 정보를 조회하고 DSRC 제어기에 설정한다.
     *  기존에 존재하는 설정정보를 삭제하고 다시 설정
     *  (데이터가 너무 많아 Delay 가 생길경우 최초에 한번만 실행하고 주기적으로 업데이트 하는 방법으로 수정가능)
     */
    private boolean loadOffrSectInfo() {
        // DSRC 제공구간 목록을 조회해서 DSRC 제어기에 설정한다.
        // 기존 제어기의 목록을 삭제한다.
        for (Map.Entry<String, TbRseCtlr> obj : AppRepository.getInstance().getCtlrMap().entrySet()) {
            obj.getValue().getOffrSectMap().clear();    // 제공구간 목록 초기화
            this.offrInfrHsList.clear();                // 제공이력 목록 삭제
        }
        try {
            List<TbRseOffrSect> list = this.rseOffrSectMapper.selectRseOffrSectAll();
            this.offrSectInfoMap.clear();
            for (TbRseOffrSect vo : list) {
                this.offrSectInfoMap.put(vo.getOFFR_SECT_ID(), vo);
                TbRseCtlr obj = AppRepository.getInstance().getCtlrMap().get(vo.getRSE_CTLR_NMBR());
                if (obj == null) {
                    log.error("loadOffrSectInfo, DSRC Not Found: {}", vo.getRSE_CTLR_NMBR());
                }
                else {
                    obj.getOffrSectMap().put(vo.getOFFR_SECT_ID(), vo);
                }
            }
        }
        catch(Exception e) {
            log.error("loadOffrSectInfo Error: {}", e);
        }
        log.info("loadOffrSectInfo: {} EA.", this.offrSectInfoMap.size());
        return true;
    }

    /*
     *  DSRC 제공구간 소통정보를 조회한다.
     */
    private boolean loadOffrSectTraf() {
        try {
            List<voDsrcOffrSectTraf> list = this.rseOffrSectMapper.selectRseOffrSectTraf();
            this.offrSectTrafMap.clear();
            for (voDsrcOffrSectTraf vo : list) {
                this.offrSectTrafMap.put(vo.getOFFR_SECT_ID(), vo);
            }
        }
        catch(Exception e) {
            log.error("loadOffrSectTraf Error: {}", e);
        }
        log.info("loadOffrSectTraf: {} EA.", this.offrSectTrafMap.size());
        return true;
    }

    public int insertDsrcOffrInfrHs(List<TbRseOffrSectTraf> list) {
        // TODO: Transaction 으로 처리하자
        // 모든 제어기의 제공이력이 리스트에 들어가 있음
        for (TbRseOffrSectTraf vo : list) {
            this.rseOffrSectMapper.insertRseOffrSectTrafHs(vo);
        }
        int jobCnt = list.size();
        list.clear();
        return jobCnt;
    }

}
