package com.its.app;

import com.its.app.config.AppUtils;
import com.its.app.config.ServerConfig;
import com.its.app.process.DbmsJobProcess;
import com.its.app.service.CctvService;
import com.its.app.service.UnitSystService;
import com.its.app.service.WcamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.ApplicationPidFileWriter;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.scheduling.annotation.EnableAsync;

@Slf4j
@EnableAsync
@Configuration
@SpringBootApplication
@ComponentScan(basePackages = {"com.its.app.config", "com.its.app.mapper", "com.its"})
public class CommunicationServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplicationBuilder()
                .sources(CommunicationServerApplication.class)
                .listeners(new ApplicationPidFileWriter("./conf/icmp-ping-server.pid"))
                .build();
        application.run(args);
        //SpringApplication.run(CommunicationServerApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {

        ServerConfig serverConfig = (ServerConfig) AppUtils.getBean(ServerConfig.class);
        log.info("");
        log.info("");
        log.info("************************************************************************************");
        log.info("**                                                                                **");
        log.info("**                         Intelligent Traffic System                             **");
        log.info("**                          ICMP Ping Server Program.                             **");
        log.info("**                                                                                **");
        log.info("**                                                                   [ver.1.0]    **");
        log.info("**          {}", serverConfig.getProcessId());
        log.info("** startup: {}", serverConfig.getBootingDateTime());
        log.info("************************************************************************************");

        // init application
        DbmsJobProcess dbmsJobProcess = (DbmsJobProcess)AppUtils.getBean(DbmsJobProcess.class);
        dbmsJobProcess.run();

        UnitSystService unitSystService = (UnitSystService)AppUtils.getBean(UnitSystService.class);
        unitSystService.loadMaster();
        unitSystService.updateUnitSyst(true);

        CctvService cctvService = (CctvService)AppUtils.getBean(CctvService.class);
        cctvService.loadDb();
        cctvService.doJob();

        WcamService wcamService = (WcamService)AppUtils.getBean(WcamService.class);
        wcamService.loadDb();
        wcamService.doJob();

        //UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
        //udpServerCenterComm.run();

        // schedule enable
        serverConfig.setStartSchedule(true);
    }

    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        log.error("Application Terminated: {}", event.getTimestamp());
        UnitSystService unitSystService = (UnitSystService) AppUtils.getBean(UnitSystService.class);
        unitSystService.updateUnitSyst(false);

        CctvService cctvService = (CctvService)AppUtils.getBean(CctvService.class);
        cctvService.updateCtlrStts(false);
        
        WcamService wcamService = (WcamService)AppUtils.getBean(WcamService.class);
        wcamService.updateCtlrStts(false);

        //UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
        //udpServerCenterComm.getNioEventLoopGroup().shutdownGracefully();
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        //System.err.println("InitializingBean 인터페이스 구현 메서드입니다. 'Bean'이 생성될 때 마다 호출되는 메서드 입니다.");
    }
    @Override
    public void destroy() throws Exception {
        //System.err.println("DisposableBean 인터페이스 구현 메서드입니다. 'Bean'이 소멸될 때 마다 호출되는 메서드입니다");
    }

    /*@Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            System.out.println("Let's inspect the beans provided by Spring Boot:");
            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                System.out.println(beanName);
            }
        };
    }*/

}
