package nlib.cmm.service;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import nlib.util.StringUtil;

/**
 * <pre>
 * @Class Name : NlibProperty.java
 * 
 * @Description : NLIB용 프로퍼티 파일을 읽어서 메모리에 로딩하고 관리하는 클래스 
 * 
 * 
 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
 *
 * </pre>
 *
 * @ ------------    --------    ---------------------------
 * @ 수정일                     수정자             수정내용
 * @ ------------    --------    ---------------------------
 * @ 2021. 7. 16.    KNKIM       최초 생성
 *
 * 
 * @author 이씨플라자 * DIGITALSHIP KNKIM
 * @since 2021. 7. 16.
 * @version 1.0
 *
 */
@Service("nlibProperty")
public class NlibProperty {
	
	private static final Logger log = LoggerFactory.getLogger(NlibProperty.class);

	/**
	 * 메모리에 로딩될 프로퍼티 객체 선언 
	 */
	public static Properties properties = null;
	
	/**
	 * nlib.properties 파일로 부터 속성을 읽어 들인다. 
	 * 
	 * @return 정상적으로 로딩한 건수를 리턴한다. 오류 발생 시, 음수값이 리턴된다. 
	 */
	public static int loadProperties() {
		
		String nlibPropPath = null;
		int propCount = -1;
		
		try {
			
            if(properties == null) properties = new Properties();
            else properties.clear();
            
			nlibPropPath = NlibProperty.class.getResource("").getPath();
			nlibPropPath = nlibPropPath.substring(0, nlibPropPath.lastIndexOf("/nlib/") + 6) + "nlib.properties";
			
			log.debug("NLIB Properties File Path : " + nlibPropPath);

	        try (InputStream input = new FileInputStream(nlibPropPath)) {

	        	properties.load(input);
	            
	            Enumeration<String> propEnum = (Enumeration<String>)properties.propertyNames();
	            
	            String propName = null;
	            while(propEnum.hasMoreElements()) {
	            	propName = propEnum.nextElement();
	            	log.debug("Loading NLIB Properties : " + propName + " = " + properties.getProperty(propName));
	            }
	            
	            log.debug("Loading is Done!");

	            propCount = properties.size();
	            
	        } catch (IOException ex) {
	            if(properties != null) properties.clear();
	            log.error("Error in Loading NLIB Properties : " + nlibPropPath);
	            ex.printStackTrace();
	            return -2;
	        }
	        
		} catch(Exception e) {
			if(properties != null) properties.clear();
            log.error("Error in Solving NLIB Properties Path : " + nlibPropPath);
            e.printStackTrace();
            return -3;
		}

		return propCount;
	}
	
	/**
	 * name 값을 키로하는 속성값을 리턴한다.
	 * 
	 * @param name
	 * @return
	 */
	public static String getProperty(String name) {
		
		if(properties == null || properties.size() < 1) {
			if(loadProperties() < 0) return null;
		}
		
		String value = properties.getProperty(name);
		if(value != null) value = value.trim();
		
		return value;
	}
	
	/**
	 * name 값을 키로하는 속성값을 문자열 형태로 리턴한다. (getProperty(..)와 동일)
	 * 
	 * @param name
	 * @return
	 */
	public static String getString(String name) {
		return getProperty(name);
	}
	
	public static String getString(String name, String defaultValue) {
		String val = getProperty(name);
		
		if(StringUtil.isEmpty(val)) return defaultValue;
		
		return val;
	}
	
	/**
	 * name 값을 키로하는 속성값을 정부형태로 리턴한다. 
	 * 만일 값이 부재이거나 정부값으로 적합하지 않을 경우, defaultValue를 리턴한다.
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public static int getInt(String name, int defaultValue) {
		try {
			return getInt(name);
		} catch(Exception e) {
			log.error("[속성값 읽기 오류] " + e.toString());
			return defaultValue;
		}
		
	}

	/**
	 * name 값을 키로하는 속성값을 정부형태로 리턴한다.
	 * 
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public static int getInt(String name) throws Exception {
		
		if(StringUtil.isEmpty(name)) {
			throw new Exception("속성값의 명칭 정보가 부적합합니다.");
		}
		
		String val = getProperty(name);
		
		if(StringUtil.isEmpty(val)) {
			throw new Exception("해당 속성값이 존재하지 않습니다.");
		}

		return Integer.parseInt(val.trim());
	}
	
}
