package com.tsi.api.server;

import com.tsi.api.server.config.TsiApiServerConfig;
import com.tsi.api.server.mybatis.TsiDatabaseService;
import com.tsi.api.server.mybatis.vo.AbstractDbmsVo;
import com.tsi.api.server.mybatis.vo.AlarmOccrVo;
import com.tsi.api.server.repository.TsiAlarmManager;
import com.tsi.api.server.vo.TsiAlarmConfigVo;
import com.tsi.app.common.app.AppUtils;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
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 javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
@MapperScan(basePackageClasses = TsiApiServerApplication.class)
@SpringBootApplication
@ComponentScan(basePackages = {"com.tsi.app.common", "com.tsi.api.server.config", "com.tsi.api.server"})
public class TsiApiServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {

    private static String applicationName = "tsi-api-server";

    @PostConstruct
    public void started() {
/*
        TimeZone.setDefault(TimeZone.getTimeZone(applicationProperties.getTimeZone()));
        System.out.println("....................................... started: " + new Date());
*/
    }

    public static void main(String[] args) {
        SpringApplication application = new SpringApplicationBuilder()
                .sources(TsiApiServerApplication.class)
                .listeners(new ApplicationPidFileWriter("./conf/" + applicationName + ".pid"))
                .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("**                               TSI CVIM System                                  **");
        log.info("**                           CVIM API Server Program.                             **");
        log.info("**                                                                                **");
        log.info("**                                                                   [ver.1.0]    **");
        log.info("** startup: {}", sdfDate.format(new Date()));
        log.info("************************************************************************************");

        try {
            TsiApiServerConfig config = (TsiApiServerConfig) AppUtils.getBean(TsiApiServerConfig.class);
            TsiAlarmManager.getInstance().getProcessStateVo().setProcessId(config.getName());

            TsiDatabaseService tsiDatabaseService = (TsiDatabaseService) AppUtils.getBean(TsiDatabaseService.class);
            AlarmOccrVo alarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
            alarm.setAlarmCode(TsiAlarmConfigVo.SYS_00);
            alarm.setAlarmTarget(config.getName());
            alarm.setAlarmValue("Running");
            tsiDatabaseService.insertAlarmOccrHs(alarm);
            tsiDatabaseService.updateProcessState(0);
        }
        catch(Exception e) {
            // no logging
        }
    }

    @Override
    public void destroy() throws Exception {

    }

    @Override
    public void afterPropertiesSet() throws Exception {

    }

    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TsiDatabaseService tsiDatabaseService = (TsiDatabaseService)AppUtils.getBean(TsiDatabaseService.class);
        try {
            // 시스템 종료 알람 이력 저장
            AlarmOccrVo alarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
            alarm.setAlarmCode(TsiAlarmConfigVo.SYS_00);
            alarm.setAlarmTarget(TsiAlarmManager.getInstance().getProcessStateVo().getProcessId());
            alarm.setAlarmValue("Terminated");
            tsiDatabaseService.insertAlarmOccrHs(alarm);
            tsiDatabaseService.updateProcessState(2);
        } catch (Exception e) {
            // no logging
        }
        log.error("Application Terminated: {}, {}", sdfDate.format(new Date()), contextClosedEvent.toString());
    }
}
