package com.its.pis.xnettcp.vds.process;

import com.its.app.AppUtils;
import com.its.app.utils.SysUtils;
import com.its.pis.ui.MainUI;
import com.its.pis.entity.TbVdsCtlr;
import com.its.pis.entity.TbVdsDtct;
import com.its.pis.entity.voVdsDtctClct;
import com.its.pis.process.DbmsJobData;
import com.its.pis.process.DbmsJobProcess;
import com.its.pis.process.DbmsJobType;
import com.its.pis.xnettcp.vds.protocol.VdsResFramePacket;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
public class Job_Data implements JobProtocol {

	private final VdsResFramePacket packet;

	@Override
	public int parse() {
		// 교통정보 데이터 수신
		if (this.packet == null || this.packet.getVdsObj() == null) {
			log.error("Job_Data, packet or object data null");
			return 0;
		}

		TbVdsCtlr obj = this.packet.getVdsObj();
		byte[] body = this.packet.getBody();
		if (body == null || body.length < 5) {
			log.error("[{}]. Job_Data: Data Length Error, {}", obj.getVDS_CTLR_ID(), (body == null) ? 0 : body.length);
			return 0;
		}

		String CLCT_DT = SysUtils.getSysTime();
		for (Map.Entry<String, TbVdsDtct> e : obj.getVdsDtctMap().entrySet()) {
			TbVdsDtct dtct = e.getValue();
			dtct.getClct().initVal();
			dtct.getClct().setVDS_DTCT_NMBR(dtct.getVDS_DTCT_NMBR());
			dtct.getClct().setTRAF_CLCT_CYCL(obj.getTRAF_CLCT_CYCL());
			dtct.getClct().setCLCT_DT(CLCT_DT);
		}

		int FrameNo = body[0];
		byte stts1  = body[1];
		byte stts2  = body[2];
		byte stts3  = body[3];
		byte stts4  = body[4];

		// 차로별 교통 정보 : 9 Byte * (차로 수)

//		Byte 7		Lane 1 교통량 (Volume)
//		Byte 8		Lane 1 평균 속도
//		Byte 9		Lane 1 점유율 정수부분 (Occupancy) (점유율 소수2자리까지 표현)
//		Byte 10		Lane 1 점유율 소수부분 (Occupancy)
//		Byte 11		Lane 1 평균 차량 길이 (dm : decimal meter, 1 dm = 1/10 m)
//		Byte 12		Lane 1 평균 차두시간 (1byte 정수)
//		Byte 13		Lane 1 공간 점유율 정수부분 (Space   Occupancy)	(점유율 소수2자리까지 표현)
//		Byte 14		Lane 1 공간 점유율 소수부분 (Space   Occupancy)
//		Byte 15		Lane 1 공간 평균속도 (1byte 정수)

		int pktLen = body.length;
		int laneCnt = (body.length - 5) / 9;

		log.info("[{}]. Job_Data: pktLen {}, laneCnt {}", obj.getVDS_CTLR_ID(), pktLen, laneCnt);

		int   idx, tfvl, spd, occ1, occ2, lngt, hdwy, spc_occ1, spc_occ2, spc_spd;
		float occ, spc_occ;
		for (int ii = 0; ii < laneCnt; ii++) {
			idx = (ii * 9) + 5;

			tfvl     = body[idx];
			spd      = body[idx+1];
			occ1     = body[idx+2];
			occ2     = body[idx+3];
			lngt     = body[idx+4];
			hdwy     = body[idx+5];
			spc_occ1 = body[idx+6];
			spc_occ2 = body[idx+7];
			spc_spd  = body[idx+8];

			occ  = (float)(occ1 + (occ2 * 0.01));
			spc_occ  = (float)(spc_occ1 + (spc_occ2 * 0.01));

			String DETECT_LANE = Integer.toString(ii+1);

			log.info("[{}]. Job_Data: Lane:{}, TFVL:{}, SPED:{}, OCPY:{}, LNGT:{}, HDWY:{}, SPCE_OCPY:{}, SPCE_SPED:{}",
					obj.getVDS_CTLR_ID(), DETECT_LANE, tfvl, spd, occ, lngt, hdwy, spc_occ, spc_spd);

			TbVdsDtct dtct = obj.getVdsDtctMap().get(DETECT_LANE);
			if (dtct == null) {
				log.error("[{}]. Job_Data: Unknown Lane No {}.", obj.getVDS_CTLR_ID(), DETECT_LANE);
			} else {
				if (tfvl > dtct.getMAX_TFVL() || tfvl < dtct.getMIN_TFVL()) {
					log.error("[{}]. Job_Data: TFVL Error Lane No {}. {}/{}/{}", obj.getVDS_CTLR_ID(), DETECT_LANE, tfvl, dtct.getMAX_TFVL(), dtct.getMIN_TFVL());
					continue;
				}
				dtct.getClct().setTFVL(tfvl);

				if (spd > dtct.getMAX_SPED() || spd < dtct.getMIN_SPED()) {
					log.error("[{}]. Job_Data: SPED Error Lane No {}. {}/{}/{}", obj.getVDS_CTLR_ID(), DETECT_LANE, spd, dtct.getMAX_SPED(), dtct.getMIN_SPED());
					continue;
				}
				dtct.getClct().setSPED(spd);

				if (occ > dtct.getMAX_OCPY_RATE() || spd < dtct.getMIN_OCPY_RATE()) {
					log.error("[{}]. Job_Data: OCPY Error Lane No {}. {}/{}/{}", obj.getVDS_CTLR_ID(), DETECT_LANE, occ, dtct.getMAX_OCPY_RATE(), dtct.getMIN_OCPY_RATE());
					continue;
				}
				dtct.getClct().setAVRG_OCPY_RATE(occ);

				dtct.getClct().setHDWY(hdwy);
				dtct.getClct().setAVRG_LNGT(lngt);
				dtct.getClct().setSPCE_OCPY_RATE(spc_occ);
				dtct.getClct().setSPCE_AVRG_SPED(spc_spd);
			}
		}

		//수집한 교통정보를 데이터베이스에 저장
		List<voVdsDtctClct> dtctClctList = Collections.synchronizedList(new ArrayList<>());
		for (Map.Entry<String, TbVdsDtct> e : obj.getVdsDtctMap().entrySet()) {
			TbVdsDtct dtct = e.getValue();
			dtctClctList.add(dtct.getClct());
		}

		DbmsJobProcess dbmsJobProcess = (DbmsJobProcess) AppUtils.getBean(DbmsJobProcess.class);
		if (dtctClctList.size() > 0) {
			dbmsJobProcess.add(new DbmsJobData(DbmsJobType.DATA_TYPE_DTCT_CLCT, false, dtctClctList));
		}

		MainUI mainUI = MainUI.getInstance();
		if (mainUI != null) {
			mainUI.updateCtlrStts(obj);
		}

		return 1;
	}

}
