package me.chyxion.tigon.propsconfig;

import java.io.File;
import org.slf4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.FileInputStream;
import org.slf4j.LoggerFactory;

/**
 * @version 0.0.1
 * @since 0.0.1
 * @author Shaun Chyxion <br>
 * chyxion@163.com <br>
 * Oct 13, 2015 11:25:55 AM
 */
public class PropsConfig {
    private static final Logger log = 
        LoggerFactory.getLogger(PropsConfig.class);
    public static final Properties CONFIG_PROPS = 
        new Properties();
    static { load(); }

    /**
     * get app (container/tomcat) dir 
     * @return app dir
     */
    public static File getAppDir() {
        File file = new File(
            // classes
            PropsConfig.class.getResource("/").getFile())
            // WEB-INF
            .getParentFile()
            // WebApp
            .getParentFile()
            // WebApps
            .getParentFile()
            // App
            .getParentFile();
        log.info("Get App Dir [{}].", file.getAbsolutePath());
        return file;
    }

    // --
    // private methods

    /**
     * load system config
     */
    static void load() {
        InputStream configIn = null;
        String configPath = "/spring/config.properties";
        try {
            log.info("Load Classpath Config [{}].", configPath);
            configIn = PropsConfig.class
                .getResourceAsStream(configPath);
            if (configIn != null) {
                log.info("Classpath Config [{}] Found.", configPath);
                CONFIG_PROPS.load(configIn);
            }
            else {
                log.warn("No Classpath Config [{}] Found.", configPath);
            }
        }
        catch (Exception e) {
            log.error("Load Classpath Config [{}] Error Caused.", configPath, e);
        }
        finally {
            if (configIn != null) {
                try {
                    configIn.close();
                }
                catch (IOException e) {
                    log.warn("Config Input Stream Close Eroror Caused.");
                }
            }
        }
        File appDir = getAppDir();
        // load global config
        load(appDir.getParentFile());
        // load app config
        load(appDir);
        log.debug("Config Props [{}] Loaded.", CONFIG_PROPS);
    }

    static void load(File dir) {
        // load from custom file
        File configFile = new File(dir, "config/config.properties");
        String configPath = configFile.getAbsolutePath();
        log.info("Load Config From Path [{}].", configPath);
        if (configFile.exists()) {
            log.info("Config File [{}] Exists.", configPath);
            InputStream configIn = null;
            try {
                configIn = new FileInputStream(configFile);
                Properties props = new Properties();
                props.load(configIn);
                log.debug("Config Props [{}] Found.", props);
                CONFIG_PROPS.putAll(props);
            }
            catch (Exception e) {
                log.error("Load Config [{}] Error Caused.", configPath, e);
            }
            finally {
                if (configIn != null) {
                    try {
                        configIn.close();
                    }
                    catch (IOException e) {
                        log.warn("Config Input Stream Close Error Caused.");
                    }
                }
            }
        }
        else {
            log.info("Config File [{}] Does Not Exist, Ignore.", configPath);
        }
    }
}
