/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.ejweb.conf;

import com.ckfinder.connector.ServletContextFactory;
import com.ejweb.core.security.DES3Utils;
import com.ejweb.core.utils.StringUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 全局配置类
 * @author ThinkGem
 * @version 2014-06-25
 */
public class GConstants {
    private static Logger LOG = Logger.getLogger(GConstants.class);
    public static final int HASH_INTERATIONS = 1024;
    public static final int SALT_SIZE = 8;

    // 常用系统属性
    public static final String   LS = System.getProperty("line.separator");// 文本换行符
    public static final String   FS = "/";//System.getProperty("file.separator");// 文件分隔符
    public static final int      BUFFER_SIZE = 8192;// 新建BYTE缓存大小，8*1024;
    public static final String   SEMICOLON   = ";";// 分号
    private static final String  CONF_DESC_KEY      = "782790337169117184";
    public static  final String[] resources = new String[]{"mybatis-refresh.properties", "jdbc.properties", "ejweb.properties", "ldap.properties"};// 越靠后越配置的值权限越高，即后面的同名变量会覆盖前面的变量
    public final static  Map<String, Boolean> FILE_FILTERS = new HashMap<String, Boolean>(10);// 文件过滤，
    
    public static final String SHOW = "1";// 显示/隐藏
    public static final String HIDE = "0";// 显示/隐藏

    public static final String YES = "1";// 是/否
    public static final String NO = "0";// 是/否
    public static final String OK  = "OK";// 是/否

    public static final String TRUE = "true";// 对/错
    public static final String FALSE = "false";// 对/错
    
    private static final  Properties P = new Properties();// 属性变
    private static final  GConstants C = new GConstants();// 单实体类

    public static final String  DEFAULT_APP_CODE   = GConstants.getValue("default.app.code", "00000");
    public static final boolean FILE_ALLOW_THUMBS  = GConstants.getBoolean("file.image.thumb.is.allow", true);

    public static final String  USERFILES_BASE_URL = GConstants.getValue("userfiles.prefix");;
    public static final String  IMAGE_BASE_URL     = GConstants.getValue("file.prefix.url");// 文件读取URL前缀
    public static final String  FILE_UPLOAD_DIR    = GConstants.getValue("file.upload.dir");// 文件上传地址
    public static final String  FILE_PREFIX_URL    = GConstants.getValue("file.prefix.url");// 文件读取URL前缀
    public static final String  FILE_TMP_DIR       = FILE_UPLOAD_DIR+"tmp";// 临时文件地址
    public static final String  PATH_FORMAt        = GConstants.getValue("file.path.format", "{yyyy}{mm}{dd}");
    public static final String  FILE_IMAGE_THUMBS  = "thumbs";// 缩略图文件顶级路径名称 201605/thumbs/images/user/png/0d7ed36548c9ea6586363d4de5cb322c.png
    public static final String  FILE_IMAGE_ACTUALS = "actuals";// 原图文件顶级路径名称  201605/actuals/images/user/png/0d7ed36548c9ea6586363d4de5cb322c.png
    public static final String  PUSH_SERVER_URL    = GConstants.getValue("push.server.url");// 推送服务器地址
    public static final int     PAGE_SIZE          = GConstants.getIntValue("page.size", 20);// 默认分页条数，默认10条
    public static final int     MAX_UPLOAD_SIZE    = GConstants.getIntValue("file.max.upload.size", 10485760);// 允许最多上传文件大小，默认10M
    public static final String  FAQ_BASE_API =  GConstants.getValue("faq.base.api"); // 接口地址
    public static final String  ORG_DISPLAY_NAME = GConstants.getValue("user.office.name", "");// 登录区域
    /**
     * 获取当前对象实例
     */
    public static GConstants getInstance() {
        return C;
    }
    private GConstants(){
        // 加载基本配置文件
        InputStream is = null;
        ResourceLoader resourceLoader = null;
        Resource resource = null;
        for(String location:resources){// 加载配置文件
            try {
                resourceLoader = new DefaultResourceLoader();
                resource = resourceLoader.getResource(location);
                is = resource.getInputStream();
                P.load(is);

                LOG.debug("加载ejweb.properties成功");
            } catch (Exception e) {
                LOG.info("加载ejweb.properties失败", e);
            } finally {
                IOUtils.closeQuietly(is);
            }
        }
        try {
            Enumeration<?> enu = P.propertyNames();  
            while (enu.hasMoreElements()) {
                try {
                    String key = (String) enu.nextElement();
                    String val = (String) P.get(key);
                    String decorded = DES3Utils.decrypt(val, CONF_DESC_KEY);
                    if(decorded != null){
                        P.put(key, decorded);
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        try {
            // 上传文件扩展名称限制
            String extensions = GConstants.getValue("file.allow.extensions");
            if(extensions != null && extensions.contains(SEMICOLON)){
                if(extensions.length() != 0){
                    String[] patternList = extensions.split(SEMICOLON);
                    for (String ext : patternList) {
                        if(ext.trim().length() != 0){
                            FILE_FILTERS.put(ext.trim().toLowerCase(), false);
                        }
                   }
                }
            }
            // 图片后缀文件
            extensions = GConstants.getValue("file.image.extensions");
            if(extensions != null && extensions.contains(SEMICOLON)){
                if(extensions.length() != 0){
                    String[] patternList = extensions.split(SEMICOLON);
                    for (String ext : patternList) {
                        if(ext.trim().length() != 0){
                            FILE_FILTERS.put(ext.trim().toLowerCase(), true);
                        }
                   }
                }
            }
            // 临时文件夹路径
            if(P.getProperty("file.upload.dir") != null){
                File tmp = new File(P.getProperty("file.upload.dir")+"tmp");
                if(!tmp.exists())
                    tmp.mkdirs();
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    
    /**
     * 获取属性，以自定义属性优先，然后回去系统属性
     * @param key
     * @return
     */
    public static String getValue(String key) {
        if(key == null)
            return null;
        if (P.containsKey(key)) {
            return P.getProperty(key);
        }
        return System.getProperty(key);
    }
    public static String getValue(String key, String want) {
        String val = getValue(key);
        if(val == null)
            return want;
        return val;
    }
    /**
     * 解析为Boolean类型
     * @param key
     * @param want
     * @return
     */
    public static boolean getBoolean(String key, boolean want) {
        String val = getValue(key);
        if(val == null || val.length() == 0)
            return want;
        try {
            return Boolean.parseBoolean(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    /**
     * 获取整型数据，转换数据类型
     * @param key
     * @param want
     * @return
     */
    public static int getIntValue(String key, int want) {
        String val = getValue(key);
        if(val == null || val.length() == 0)
            return want;
        try {
            return Integer.parseInt(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    /**
     * 获取长整型数据
     * @param key
     * @param want
     * @return
     */
    public static long getLongValue(String key, long want) {
        String val = getValue(key);
        if(val == null || val.length() == 0)
            return want;
        try {
            return Long.parseLong(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    public static float getFloatValue(String key, float want) {
        String val = getValue(key);
        if(val == null || val.length() == 0)
            return want;
        try {
            return Float.parseFloat(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    public static double getDoubleValue(String key, double want) {
        String val = getValue(key);
        if(val == null || val.length() == 0)
            return want;
        try {
            return Double.parseDouble(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    /**
     * 获取管理端根路径
     */
    public static String getAdminPath() {
        return getValue("adminPath");
    }
    
    /**
     * 获取前端根路径
     */
    public static String getFrontPath() {
        return getValue("frontPath");
    }
    
    /**
     * 获取URL后缀
     */
    public static String getUrlSuffix() {
        return getValue("urlSuffix");
    }
    
    /**
     * 是否是演示模式，演示模式下不能修改用户、角色、密码、菜单、授权
     */
    public static Boolean isDemoMode() {
        String dm = getValue("demoMode");
        return "true".equals(dm) || "1".equals(dm);
    }
    /**
     * 在修改系统用户和角色时是否同步到Activiti
     * 
     * @author renmb
     * @time  2017年4月17日
     * @return
     */
    public static Boolean isSynActivitiIndetity() {
        String dm = getValue("activiti.isSynActivitiIndetity", "false");
        return "true".equals(dm) || "1".equals(dm);
    }
    /**
     * 页面获取常量
     */
    public static Object getConst(String field) {
        try {
            return GConstants.class.getField(field).get(null);
        } catch (Exception e) {
            // 异常代表无配置，这里什么也不做
        }
        return null;
    }

    /**
     * 获取上传文件的根目录
     * @return
     */
    public static String getUserfilesBaseDir() {
        String dir = FILE_UPLOAD_DIR;//getValue("file.upload.dir");
        if (StringUtils.isBlank(FILE_UPLOAD_DIR)){
            try {
                dir = ServletContextFactory.getServletContext().getRealPath("/");
            } catch (Exception e) {
                return "";
            }
        }
        if(!dir.endsWith("/")) {
            dir += "/";
        }
//        System.out.println("file.upload.dir: " + dir);
        return dir;
    }
    public static String getBaseUrl(HttpServletRequest req){
        
        return IMAGE_BASE_URL;
    }
    /**
     * 获取工程路径
     * @return
     */
    public static String getProjectPath(){
        // 如果配置了工程路径，则直接返回，否则自动获取。
        String projectPath = GConstants.getValue("projectPath");
        if (StringUtils.isNotBlank(projectPath)){
            return projectPath;
        }
        try {
            File file = new DefaultResourceLoader().getResource("").getFile();
            if (file != null){
                while(true){
                    File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
                    if (f == null || f.exists()){
                        break;
                    }
                    if (file.getParentFile() != null){
                        file = file.getParentFile();
                    }else{
                        break;
                    }
                }
                projectPath = file.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return projectPath;
    }
}
