package com.its.dsrc.scheduler;

import com.its.app.utils.Elapsed;
import com.its.app.utils.StatisticsTime;
import com.its.dsrc.config.RunningConfig;
import com.its.dsrc.config.ApplicationConfig;
import com.its.dsrc.service.RseCtlrService;
import com.its.dsrc.service.RseSectService;
import com.its.dsrc.service.StatisticsServices;
import com.its.dsrc.service.UnitSystService;
import com.its.dsrc.xnettcp.dsrc.process.service.MultiMediaDataService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

@Slf4j
@AllArgsConstructor
@EnableScheduling
@Component
public class SchedulerTask {

    private final ApplicationConfig applicationConfig;
    private final RunningConfig runningConfig;
    private final UnitSystService unitSystService;
    private final RseCtlrService rseCtlrService;
    private final RseSectService rseSectService;
    private final StatisticsServices statisticsServices;

    @PreDestroy
    public void onShutDown() {
         this.unitSystService.updateUnitSystStts(false);
    }

    @Scheduled(cron = "5 * * * * *")  // 1분주기 작업 실행
    public void scheduleUnitSystStts() {
        if (!this.applicationConfig.isStartSchedule()) {
            return;
        }
        Elapsed elapsed = new Elapsed();
        log.info("unitSystStts: start. {}", Thread.currentThread().getName());
        // 1. 프로세스 상태정보 업데이트
        this.unitSystService.updateUnitSystStts(true);
        // 1. 제어기 상태정보 업데이트(제어기/프로세스 상태정보 UDP 전송)
        this.rseCtlrService.updateCtlrStts(true);
        log.info("unitSystStts: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
    }

    //@Scheduled(cron = "1 0/5 * * * ?")  // 5분주기 작업 실행(DSRC 구간 소통정보 생성)
    @Scheduled(cron = "50 4,9,14,19,24,29,34,39,44,49,54,59 * * * *")  // 5분주기 작업 실행(DSRC 구간 소통정보 생성)
    public void scheduleMakeSectTraf() {
        if (!this.applicationConfig.isStartSchedule()) {
            return;
        }
        Elapsed elapsed = new Elapsed();
        log.info("makeSectTraf: start. {}", Thread.currentThread().getName());
        this.rseSectService.makeDsrcSectTraffic();
        log.info("makeSectTraf: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
    }

    @Scheduled(cron = "30 0/5 * * * *")  // DSRC Multimedia 작업 실행 ==> 교통정보 가공이 완료된 후에 실행
    public void scheduleMultimedia() {
        if (!this.applicationConfig.isStartSchedule()) {
            return;
        }

        if (this.runningConfig.isPublicationMultimedia()) {
            Elapsed elapsed = new Elapsed();
            log.info("multimedia..: start. {}", Thread.currentThread().getName());
            MultiMediaDataService.getInstance().makeMultimediaData();
            log.info("multimedia..: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
        }
    }

    @Scheduled(cron = "40 0/5 * * * *")    // 정주기 5분 40초에 스케쥴 실행
    public void schedule5M() {
        if (!this.applicationConfig.isStartSchedule()) {
            return;
        }
        Elapsed elapsed = new Elapsed();
        log.info("schedule5M..: start. {}", Thread.currentThread().getName());
        if (this.applicationConfig.isStatistics()) {
            StatisticsTime its = new StatisticsTime();
            its.init();
            its.setProcessing(true);

            if (its.isStatHour()) {
                // 매시 5분 가공완료후 1시간 통계
                this.statisticsServices.CRT_TB_RSE_OBU_CLCT_STAT_HH(its.getStatHourTime(), its.getStatHourTime(), its.getStatHourTo());
                this.statisticsServices.CRT_TB_RSE_OD_STAT_HH(its.getStatHourTime(), its.getStatHourTime(), its.getStatHourTo());
            }

            if (its.isStatDay()) {
                // 00시 10분 가공이 끝나면 이전일의 통계 정보를 가공.
                this.statisticsServices.CRT_TB_RSE_OBU_CLCT_STAT_DD(its.getStatDayFrom(), its.getStatDayFrom(), its.getStatDayTo());
            }
            its.setProcessing(false);
        }
        log.info("schedule5M..: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
    }

    @Scheduled(cron = "0/10 * * * * *")  // 10초 주기 작업 실행
    public void scheduleFrED() {
        if (!this.applicationConfig.isStartSchedule()) {
            return;
        }
//        this.rseCtlrService.monitoringSession();
    }

}
