package com.ejweb.core.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ejweb.conf.GConstants;
import com.ejweb.core.security.Digests;
import com.ejweb.core.utils.Encodes;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.UUID;

public class Util {

    /**
     * 电话号格式化
     * @param phone
     * @return
     */
    public static String phoneNumberFormat(String phone){
        if(phone == null)
            return  null;
        int len = phone.length();
        if(len>=8){
//            return phone.replaceAll("(\\d{3})\\d{4}(\\d+)","$1****$2");// 正则匹配
            return phone.substring(0, 3)+"****"+phone.substring(7,len);// 字符串拼接
        }
        return  phone;
    }
    public static int parseInt(String val, int want){
        if(StringUtils.isEmpty(val))
            return want;
        try {
            return Integer.parseInt(val);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return want;
    }
    public static Date utc2Local(String utcTime) {
        
        
        try {
            String pattern = null;
            if("yyyy-MM-dd HH:mm".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd HH:mm";
            } else if("yyyy-MM-dd HH:mm:ss".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd HH:mm:ss";
            } else if("yyyy-MM-dd".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd";
            }
            SimpleDateFormat utcFormater = new SimpleDateFormat(pattern);
            utcFormater.setTimeZone(TimeZone.getTimeZone("UTC"));
//            Date utcDate = null;
            Date utcDate = utcFormater.parse(utcTime);
            return utc2Local(utcDate);
//            SimpleDateFormat localFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            localFormater.setTimeZone(TimeZone.getTimeZone("GMT-8"));
//            String localTime = localFormater.format(gpsUTCDate.getTime());
//            return localTime;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static Date utc2Local(Date utcDate) {
        try {
    //        TimeZone bjtz = TimeZone.getTimeZone("Asia/Shanghai");
    //        TimeZone bjtz = TimeZone.getDefault();
            TimeZone oldZone = TimeZone.getTimeZone("UTC");
            TimeZone newZone = TimeZone.getTimeZone("GMT+08:00");
    //        int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
            
            return changeTimeZone(utcDate, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    /**
     * 
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @return
     */
    public static Date local2Utc(Date date) {
        try {
    //        TimeZone bjtz = TimeZone.getTimeZone("Asia/Shanghai");
    //        TimeZone bjtz = TimeZone.getDefault();
            TimeZone oldZone = TimeZone.getTimeZone("GMT+08:00");
            TimeZone newZone = TimeZone.getTimeZone("UTC");
    //        int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
            
            return changeTimeZone(date, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    /**
     * 时区转换
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @param oldZone
     * @param newZone
     * @return
     */
    public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) {
        try {
            
            GregorianCalendar localGregorianCalendar1 = new GregorianCalendar(oldZone);
            localGregorianCalendar1.setTime(date);
            
            GregorianCalendar localGregorianCalendar2 = new GregorianCalendar(newZone);
            localGregorianCalendar2.setTimeInMillis(localGregorianCalendar1.getTimeInMillis());
            
            return new Date(localGregorianCalendar2.getTimeInMillis());
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    public static String getDurationTime(long time){
        
        String buffer = "";
        buffer = ":"+time%1000+"纳秒";
        time   = time/1000;//微秒
        buffer = ":"+time%1000+"微秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%1000+"毫秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%60+"秒"+buffer;
        time   = time/60;//秒
        buffer =time+"分钟"+buffer;
        return buffer;
    }
    /**
     * 获取堆栈信息
     * 
     * @author renmb
     * @time  2016年10月21日
     * @param e
     * @return
     */
    public static String getStackTrace(Throwable e) {
        
        String error = "";
        Writer errors = null;
        PrintWriter printWriter = null;
        try {
            
            errors = new StringWriter();
            printWriter = new PrintWriter(errors);
            
            e.printStackTrace(printWriter);
            error = errors.toString();
            printWriter.close();
            errors.close();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
//            e1.printStackTrace();
        }
        return error;
    }
    /**
     * 设置图片全名称
     * 
     * @author renmb
     * @time  2016年12月11日
     * @param url
     * @param want
     * @return
     */
    public static String getAbsoluteUrl(String url, String want) {
        if(StringUtils.isBlank(url))
            return getAbsoluteUrl(want);
        if(url.startsWith("http://") || url.startsWith("https://"))// 绝对路径
            return url;
        if(GConstants.FILE_PREFIX_URL.endsWith("/") && url.startsWith("/"))// 相对路径
            return GConstants.FILE_PREFIX_URL+url.replaceAll("^/+", "");
        return GConstants.FILE_PREFIX_URL+url;
    }
    /**
     * 获取文件的绝对路径
     * 
     * @author renmb
     * @time  2016年9月1日
     * @param url
     * @return
     */
    public static String getAbsoluteUrl(String url) {
        if(StringUtils.isBlank(url))
            return "";
        if(url.startsWith("http://") || url.startsWith("https://"))// 绝对路径
            return url;
        if(GConstants.FILE_PREFIX_URL.endsWith("/") && url.startsWith("/"))// 相对路径
            return GConstants.FILE_PREFIX_URL+url.replaceAll("^/+", "");
        return GConstants.FILE_PREFIX_URL+url;
    }
    /**
     * 获取相对路径地址
     * 
     * @author renmb
     * @time  2017年1月13日
     * @param url
     * @return
     */
    public static String getRelativePath(String url) {
        if(StringUtils.isBlank(url))
            return "";
        return url.replaceAll(GConstants.FILE_PREFIX_URL, "");
//        return url;
    }
    /**
     * 获取文件的扩展名称
     * @param filename
     * @return
     */
    public static String getExtensionName(String filename) {
//        if(filename == null || filename.length() == 0)
//            return null;
//        if(filename.contains(".")){
//            String[] species = filename.split("\\.");
//            return "."+species[species.length-1].toLowerCase();
//        }
//        return null;
        
        if(filename == null || filename.length() == 0)
            return "";
        int startIndex = filename.lastIndexOf(".")+1;
        int length = filename.length();
        if(startIndex>0 && startIndex<length){
            
            return "."+filename.substring(startIndex, length);
        }
        return "";
    }
    /**
     * 获取文件扩展名，不带“.”
     * 
     * @author renmb
     * @time  2017年2月10日
     * @param filename
     * @return
     */
    public static String getFileExtensionName(String filename) {
        if(filename == null || filename.length() == 0)
            return "";
        int startIndex = filename.lastIndexOf(".")+1;
        int length = filename.length();
        if(startIndex>0 && startIndex<length){
            
            return filename.substring(startIndex, length);
        }
        return "";
    }
    /**
     * 新就版本进行比较，如果新版本比老版本高则返回true，否则返回false
     * 
     * @author renmb
     * @time  2016年8月3日
     * @param oldVersion
     * @param version
     * @return
     */
    public static boolean compareVersion(String oldVersion, String version) {
        
        if(version != null && oldVersion != null) {
            String checkVersion[] = version.split("\\.");
            String originalVersion[] = oldVersion.split("\\.");
            int maxlength = (originalVersion.length >= checkVersion.length)?originalVersion.length:checkVersion.length;
            // go through all Version-parts
            for(int i= 0; i < maxlength; i++) {
                // if the checked version is too short
                if ( checkVersion.length <= i 
                    && originalVersion[i].equals(0))
                    return true;
                else if (checkVersion.length <= i)
                    return false;
                // if the original version is long enough
                if(originalVersion.length > i) {
                    
                    // convert to integer
                    try {
                        int originalVersNumber = Integer.valueOf(originalVersion[i]).intValue();
                        int checkVersNumber = Integer.valueOf(checkVersion[i]).intValue();
                        
                        // check the numbers
                        if(checkVersNumber > originalVersNumber) {
                            return true;
                        } else if(checkVersNumber < originalVersNumber) {
                            return false;
                        }
                    } catch(Exception e) {
                        return false;
                    }
                }
                else {
                    return true;
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
     */
    public static String entryptPassword(String plainPassword) {
        try {
            String plain = Encodes.unescapeHtml(plainPassword);
            byte[] salt = Digests.generateSalt(GConstants.SALT_SIZE);
            byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, GConstants.HASH_INTERATIONS);
            return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    
    /**
     * 验证密码
     * @param plainPassword 明文密码
     * @param password 密文密码
     * @return 验证成功返回true
     */
    public static boolean validatePassword(String plainPassword, String password) {
        try {
            String plain = Encodes.unescapeHtml(plainPassword);
            byte[] salt = Encodes.decodeHex(password.substring(0,16));
            byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, GConstants.HASH_INTERATIONS);
            return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
        } catch (Exception e) {
            // TODO: handle exception
        }
        return false;
    }

    public static String getGenericCode(){
        try {
            
            return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    
    public static boolean isrContainValues(JSONArray data, String... values) {
        if(data == null || values == null)
            return false;
        int count = 0;
        int len = data.size();
        for(String val:values){
            for(int j=0;j<len;j++){
                if(val !=null && val.equals(data.getString(j))){
                    count++;
                    if (count == values.length) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    public static boolean isPraramerValue(JSONObject data, String... colums) {
        if(data == null || colums == null)
            return false;
        for(String colum:colums){
            if(data.containsKey(colum) == false){
                return false;
            }
        }
        return true;
    }
    public static boolean isInValue(String val, String... vals) {
        if(val == null || vals == null)
            return false;
        for(String v:vals){
            if(val.equals(v)){
                return true;
            }
        }
        return false;
    }
    /**
     * 生成稳健的随机数
     * @param min
     * @param max
     * @return
     */
    public static int getRandom(int min, int max) {
        try {
            SecureRandom number = SecureRandom.getInstance("SHA1PRNG");
            int randomNumber = (number.nextInt(max-min+3)+min);//(int)(Math.random()*(max-min+3)+min);
            while (randomNumber == min || randomNumber == max+2) {
                randomNumber = (number.nextInt(max-min+3)+min);
            }
            return randomNumber-1;
        } catch (Exception e){

            e.printStackTrace();
        }
        int randomNumber = (int)(Math.random()*(max-min+3)+min);
        while (randomNumber == min || randomNumber == max+2) {
            randomNumber = (int)(Math.random()*(max-min+3)+min);
        }
        return randomNumber-1;
    }
    public static double getRandom(double max) {
        
        double randomNumber = Math.random()*(max+2);
        while (randomNumber >= max+1) {
            randomNumber = Math.random()*(max+2);
        }
        return randomNumber;
    }
    /**
     * 获取客户端真实IP地址
     * @param request
     * @return
     */
    public static String getOnlineIP(HttpServletRequest request) {
        //获取X-Forwarded-For
        if(request == null)
            return "Unknown";
        String ip = request.getHeader("X-Real-IP");
        if(StringUtils.isBlank(ip) || "Unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("x-forwarded-for");
            if(StringUtils.isBlank(ip) || "Unknown".equalsIgnoreCase(ip)){
                //获取HTTP_CLIENT_IP
                ip = request.getHeader("Proxy-Client-IP");
                if(StringUtils.isBlank(ip) || "Unknown".equalsIgnoreCase(ip)){
                    //HTTP_X_FORWARDED_FOR
                    ip = request.getHeader("WL-Proxy-Client-IP");
                    if(StringUtils.isBlank(ip) || "Unknown".equalsIgnoreCase(ip)){
                        ip = request.getRemoteAddr();
                    }
                }
            }
        }
        if(StringUtils.isBlank(ip))
            return "Unknown";
        return ip.split(",")[0];
    }

    /**
     * 得到请求的根目录
     * 
     * @param request
     * @return
     */
    public static String getBasePath(HttpServletRequest request) {
        try {
            String path = request.getContextPath();
            String basePath = request.getScheme() + "://" + request.getServerName()
                    + ":" + request.getServerPort() + path;
            basePath = basePath.trim().replaceAll("/+$", "");// 将结尾的反斜杠去掉
            return basePath;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    /**
     * 得到结构目录
     * 
     * @param request
     * @return
     */
    public static String getContextPath(HttpServletRequest request) {
        String path = request.getContextPath();
        return path;
    }
}
