package com.its.onvif.cmra.server;

import com.its.onvif.cmra.server.app.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.Banner;
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.event.ContextClosedEvent;

import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
@SpringBootApplication
public class OnvifCmraServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {

    private static boolean isTerminated = false;
    public static final String APPLICATION_NAME = "onvif-cmra-server";

    public static void main(String[] args) {
        SpringApplication application = new SpringApplicationBuilder()
                .sources(OnvifCmraServerApplication.class)
                .listeners(new ApplicationPidFileWriter("./conf/" + APPLICATION_NAME + ".pid"))
                .registerShutdownHook(true)
                .build();
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }

    @Override
    public void run(String... args) throws Exception {
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("");
        log.info("");
        log.info("************************************************************************************");
        log.info("**                                                                                **");
        log.info("**                            UTIC ITS ROTA System                                **");
        log.info("**                 ITS Onvif IP Camera Control Server Program.                    **");
        log.info("**                                                                                **");
        log.info("**                                                                   [ver.1.0]    **");
        log.info("** startup: {}", sdfDate.format(new Date()));
        log.info("**    HOME: {}", System.getProperty("user.home"));
        log.info("************************************************************************************");

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.error("Runtime thread: on shutdown hook.");
            terminateApplication();
        }));
    }

    public void terminateApplication() {
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("**    Application Terminated: {}, {}", sdfDate.format(new Date()), isTerminated);
        if (!isTerminated) {
            isTerminated = true;
            log.info("************************************************************************************");

            try {
                SpringApplication.exit(SpringUtils.getApplicationContext());
                System.exit(0);
            } catch (Exception e) {
                log.error("**    terminateApplication.exception: {}", e.getMessage());
            }
            log.info("************************************************************************************");
        }
    }

    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
        log.error("onApplicationEvent: {}", contextClosedEvent);
        terminateApplication();
    }

    @Override
    public void destroy() throws Exception {
        log.error("Application destroy: isTerminated({})", isTerminated);
//        Thread.getAllStackTraces().keySet().forEach(thread -> {
//                log.error("Active Thread: " + thread.getName() + " | Daemon: " + thread.isDaemon());
//                if (!thread.isDaemon()) {
//                    thread.interrupt(); // 스레드 인터럽트 호출
//                }
//            }
//        );
        SpringApplication.exit(SpringUtils.getApplicationContext());
        System.exit(0);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
    }
}
