package kr.co.uplus.ez;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.core.env.AbstractEnvironment;

import kr.co.uplus.ez.common.utils.USecuritySupUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootApplication
public class WebApplication extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(WebApplication.class);
	}

	public static void main(String[] args) throws Exception {
		if (System.getProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME) == null) {
			System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "local");
		}

		SpringApplication.run(WebApplication.class, args);
	}

	@PostConstruct
	public void onStartup() {
		// 유플러스 마스킹 유틸 적용
		USecuritySupUtils.initMaskingRule();
		
		Thread checkThread = new Thread(new CheckProcess());
		checkThread.setDaemon(true);
		checkThread.start();
		log.info("################ System-up start ################");
	}

	@PreDestroy
	public void onExit() {
		log.info("################ System-down start ################");
	}
}

/**
 * 프로세스 hang 확인을 위한 1분마다 메모리 로깅 기능 
 * 데몬 스레드 방식으로 스프링 관리 스레드 아님
 */
@Slf4j
class CheckProcess implements Runnable {

	private static final String PROC_NAME = "mhez-admin";
	@Override
	public void run() {
		while (true) {
			try {
				process();
				Thread.sleep(1000 * 60);
			} catch (InterruptedException e) {
			}
		}
	}

	private void process() {
		Runtime runtime = Runtime.getRuntime();
		long totalMemory = runtime.totalMemory() / (1024 * 1024);
		long freeMemory = runtime.freeMemory() / (1024 * 1024);
		long maxMemory = runtime.maxMemory() / (1024 * 1024);
		long usedMemory = totalMemory - freeMemory;

		log.info("{} Process Monitoring : maxMemory -> {}MB, totalMemory -> {}MB, usedMemory -> {}MB, freeMemory -> {}MB, ActiveThread -> {}",
				PROC_NAME, maxMemory, totalMemory, usedMemory, freeMemory, Thread.activeCount());
	}
}