package com.cesgroup.cesmonitor.common;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.batik.transcoder.TranscoderException;
import org.apache.shiro.util.ThreadContext;

import com.cesgroup.cesmonitor.bean.Timetemp;
import com.cesgroup.cesmonitor.service.IdentityService;
import com.cesgroup.cesmonitor.service.LoginUser;
import com.cesgroup.framework.commons.SpringContextUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 工具类
 *
 * @author zhang.erwei
 * @version 1.0.0 2017年5月24日
 */
public class Util {

    /**
     * 日期格式，年-月-日
     */
    //public static final SimpleDateFormat DF_DATE = new SimpleDateFormat("yyyy-MM-dd");
    private static ThreadLocal<DateFormat> DF_DATE = new ThreadLocal<DateFormat>() {

        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public static Date parse(final String dateStr) throws ParseException {
        return DF_DATE.get().parse(dateStr);
    }

    /**
     * 日期格式，年-月-日 时:分:秒
     */
    ///public static final SimpleDateFormat DF_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * JSON Mapp对象
     */
    public static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 判断是否为空
     *
     * @param obj
     *
     * @return 返回boolean值
     */
    public static boolean isNull(final Object obj) {
        if ((obj != null) && (!"".equals(obj))) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 判断是否非空
     *
     * @param obj
     *
     * @return 返回boolean值
     */
    public static boolean notNull(final Object obj) {
        if ((obj != null) && (!"".equals(obj.toString()))) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 将Date类型的对象转化为String
     *
     * @param date
     *
     * @param sf
     *
     * @return 将日志格式化
     */
    public static String toStr(final Date date, final SimpleDateFormat sf) {
        if (isNull(date)) {
            return "";
        }
        return sf.format(date);
    }

    /**
     *
     * @param from
     *
     * @return 返回值
     */
    public static <T> List<T> convert(final List<? extends T> from) {
        final List<T> to = new ArrayList<T>();
        for (final T a : from) {
            to.add(a);
        }
        return to;
    }

    /**
     *
     * @param obj
     *
     * @return 转换成JSON对象
     */
    public static String toJSON2(final Object obj) {
        try {

            return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (final JsonProcessingException e) {
            throw new RuntimeException("无法解析为JSON", e);
        }
    }

    /**
     *
     * @param obj
     *
     * @return 转换成JSON对象
     */
    public static String toJSON(final Object obj) {
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (final JsonProcessingException e) {
            throw new RuntimeException("无法解析为JSON", e);
        }
    }

    public static void setCurrentUser(final String username) {
        ThreadContext.put(IdentityService.LOGIN_USER, username);
    }

    /**
     *
     * @return 获取用户的登录信息
     */
    public static LoginUser getLoginUser() {
        return SpringContextUtils.getBean(IdentityService.class).getLoginUser();
        //// HttpServletRequest request =
        //// ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        // try {
        // String
        //// username=(String)org.apache.shiro.SecurityUtils.getSubject().getPrincipal();
        // if(username==null){
        // username= (String)ThreadContext.get("LoginUser");
        // }
        //// WebApplicationContext
        //// context=org.springframework.web.servlet.support.RequestContextUtils.getWebApplicationContext(request);
        //// return context.getBean("identityService",
        //// IdentityService.class).getLoginUser(username);
        // LoginUser
        //// user=SpringContextUtils.getBean(IdentityService.class).getLoginUser(username);
        //// System.out.println(Util.toJSON(user));
        // return user;
        // } catch (Throwable e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // return null;
    }

    /**
     *
     * @param str
     *
     * @param pattern
     *
     * @return 返回格式化后的日期
     */
    public static Date stringToDate(final String str, final String pattern) {
        Date date = new Date();
        // format的格式要与日期String的格式相匹配
        final DateFormat sdf = new SimpleDateFormat(pattern);
        try {
            date = sdf.parse(str);
        } catch (final ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * timestamp --> Date
     */
    public static Date timestampToDate(final Timestamp timestamp) {
        Date date = new Date();
        date = timestamp;
        return date;
    }

    /**
     * 获取时间戳格式
     *
     * @param interval
     *            时间间隔
     * @return 获取时间戳格式
     */
    public static long getTimeFormat(final Integer interval) {
        long timeFormat = 0;
        if (interval == 24) {
            timeFormat = 60 * 60; //最近24小时
        } else if (interval == 7) { // 最近7天
            timeFormat = 60 * 60 * 24;
        } else if (interval == 30) { // 最近30天
            timeFormat = 60 * 60 * 24;
        } else if (interval == 3 || interval == 6 || interval == 12) { // 最近三个月、半年或一年
            timeFormat = 60 * 60 * 24 * 30;
        }
        return timeFormat;
    }

    /**
     * 移除List大小至指定的大小
     *
     * @param <T>
     *
     * @param list
     *            集合
     * @param num
     *            指定数量
     * @return 剔除后的集合
     */
    public static <T> List<T> reduceList(final List<T> list, final int num) {
        if (num == 0) {
            return list;
        } else {
            if (list.size() > num) {
                final Iterator<T> it = list.iterator(); // 获取迭代器
                int index = 0;
                while (it.hasNext()) {
                    final T t = it.next();
                    if (index >= num) {
                        it.remove(); // 移除数据
                    }
                    index++;
                }
            }
            return list;
        }
    }

    /**
     * 获取时间间隔的截止时间戳，单位为s
     *
     * @return 时间间隔的截止时间戳
     */
    public static Long getDeadLine(final Integer interval) {
        final Calendar deadLine = Calendar.getInstance();
        deadLine.set(Calendar.HOUR_OF_DAY, 23);
        deadLine.set(Calendar.MINUTE, 59);
        deadLine.set(Calendar.SECOND, 59);
        deadLine.set(Calendar.MILLISECOND, 999);
        /* if (interval == 24 || interval == 7 || interval == 30) { //最近24小时，最近7天，最近30天
            deadLine.add(Calendar.DATE, -1);
        } else if (interval == 3) { //最近3个月
            deadLine.set(Calendar.DAY_OF_MONTH, 1);
            deadLine.add(Calendar.DATE, -1);
        }*/
        if (interval == 24 || interval == 7 || interval == 30 || interval == 3 || interval == 6
            || interval == 12) { //最近24小时，最近7天，最近30天
            deadLine.add(Calendar.DATE, -1);
        }
        return deadLine.getTime().getTime() / 1000;
    }

    /**
     * 获取昨天最后的时间戳，单位为s
     *
     * @return 昨天最后的时间戳
     */
    public static Long getYesterdayLastTimeTime() {
        final Calendar yesterdayLastTime = Calendar.getInstance();
        yesterdayLastTime.add(Calendar.DATE, -1);
        yesterdayLastTime.set(Calendar.HOUR_OF_DAY, 23);
        yesterdayLastTime.set(Calendar.MINUTE, 59);
        yesterdayLastTime.set(Calendar.SECOND, 59);
        yesterdayLastTime.set(Calendar.MILLISECOND, 999);
        return yesterdayLastTime.getTime().getTime() / 1000;
    }

    /**
     * @return 返回上一个月有多少天
     */
    public static int lastMonthOfDays() {
        final Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, 1);// 设置为当前月第一天
        c.add(Calendar.DAY_OF_MONTH, -1);// -1天得到上月最后一天
        return c.getTime().getDate();// 上个月有多少天
    }

    /**
     *
     * @return 返回至今是这个月的多少天
     */
    public static int currentMonthOfDays() {
        return new Date().getDate();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v
     *            需要四舍五入的数字
     * @param scale
     *            小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(final double v, final int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        final BigDecimal b = new BigDecimal(Double.toString(v));
        final BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     *
     * @param calendar
     *
     * @param i
     *
     * @return 返回每天的开始和结束时间戳
     */
    public static Timetemp getTime(final Calendar calendar, final int i) {
        if (i != 0) {
            calendar.add(Calendar.DAY_OF_YEAR, -1);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        final Date start = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.SECOND, -1);
        final Date end = calendar.getTime();
        final long startTemp = start.getTime() / 1000;
        final long endTemp = end.getTime() / 1000;
        final Timetemp tt = new Timetemp();
        tt.setStartTime(startTemp);
        tt.setEndTime(endTemp);
        return tt;
    }

    /**
     *
     * @param timetemp
     *
     * @return 根据时间戳返回具体年月日--时分秒格式
     */
    public static String getDate(final Long timetemp) {
        final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        final Long startTime = timetemp * 1000L;
        final Long time = new Long(startTime);
        return format.format(time);
    }

    /**
     *
     * @param diff
     *
     * @return 根据时间戳的差值计算出是几月、天、时、分、秒
     */
    public static String getDiff(final long diff) {
        final int months = (int) Math.floor(diff / (30 * 24 * 3600));
        final long leave1 = diff % (30 * 24 * 3600);
        final int days = (int) Math.floor(leave1 / (24 * 3600));
        final long leave2 = leave1 % (24 * 3600);
        final int hours = (int) Math.floor(leave2 / (3600));
        final long leave3 = leave2 % (3600);
        final int minutes = (int) Math.floor(leave3 / (60));
        final long leave4 = leave3 % (60);
        final int seconds = Math.round(Float.parseFloat(String.valueOf(leave4)));
        String returnStr = seconds + "秒";
        if (minutes > 0) {
            returnStr = minutes + "分" + returnStr;
        }
        if (hours > 0) {
            returnStr = hours + "时" + returnStr;
        }
        if (days > 0) {
            returnStr = days + "天" + returnStr;
        }
        if (months > 0) {
            returnStr = months + "月" + returnStr;
        }
        return returnStr;
    }

    /**
     * service层获取字体路径，用于pdf导出
     *
     * @return 工程中字体路径
     */
    public static String getFontPath() {
        //        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
        //            .getRequest();
        //        String fontPath = request.getSession().getServletContext().getRealPath("/fonts/simkai.ttf");
        //        String fontPath = Util.class.getResource("/com/cesgroup/cesmonitor/common/simkai.ttf").getPath();
        final String fontPath = Util.class.getResource("/simkai.ttf").getPath();
        return fontPath;
    }

    /**
     * 将bps的流量转化为kbps单位
     *
     * @param number
     *
     * @return 返回单位kbps的流量
     */
    public static Double getFlowConversion(final Double number) {
        Double newNumber = 0.0;
        newNumber = Util.round(number / 1024, 2);
        return newNumber;
    }

    /**
     * 将B的磁盘容量单位转换成GB
     *
     * @param number
     *
     * @return 返回单位GB的磁盘容量
     */
    public static Double getCapacityConversion(final Double number) {
        Double newNumber = 0.0;
        newNumber = Util.round(number / (1024 * 1024 * 1024), 2);
        return newNumber;
    }

    /**
     * 递归删除文件夹
     *
     * @param file
     *            文件夹
     */
    public static void deleteFile(final File file) {
        if (file.exists()) { //判断文件是否存在
            if (file.isFile()) { //判断是否是文件
                file.delete(); //删除文件
            } else if (file.isDirectory()) { //否则如果它是一个目录
                final File[] files = file.listFiles(); //声明目录下所有的文件 files[];
                if (files != null) {
                    for (int i = 0; i < files.length; i++) { //遍历目录下所有的文件
                        deleteFile(files[i]); //把每个文件用这个方法进行迭代
                    }
                    file.delete(); //删除文件夹
                }

            }
        } else {
            System.out.println("所删除的文件不存在");
        }
    }

    /**
     * 统一按照宽度压缩 这样来的效果是，所有图片的宽度是相等的
     *
     * @param h
     *            高度
     * @param w
     *            宽度
     * @return 比例
     */
    public static int getPercent(final float h, final float w) {
        int p = 0;
        float p2 = 0.0f;
        p2 = 450 / w * 95;
        p = Math.round(p2);
        return p;
    }

    /**
     *
     * @return 当前日期，类型为String
     */
    public static String getCurrentTime() {
        final Calendar calendar = Calendar.getInstance();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        final String currentTime = sdf.format(calendar.getTime());
        return currentTime;
    }

    /**
     * 获取图片
     *
     * @param request
     *            请求
     * @param response
     *            响应
     * @return 图片集合
     */
    public static List<String> getImgList(final HttpServletRequest request, final HttpServletResponse response) {
        final List<String> imageList = new ArrayList<String>();
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream; charset=UTF-8");
            response.setHeader("content-disposition",
                "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".pdf");

            String svgCode = request.getParameter("svg");//highcharts图表svgCode
            System.out.println(svgCode);
            //svgCode = svgCode.replace("(102, 102, 102)", "(0, 0, 0)");
            //svgCode = svgCode.replace("(51, 51, 51)", "(0, 0, 0)");
            svgCode = svgCode.replace("#666666", "#000000");

            System.out.println(svgCode);
            final String[] svg = svgCode.split("_,_"); //两张图片分开
            final String[] path = new String[svg.length];
            final String pdfPath = request.getSession().getServletContext().getRealPath("/upload/");
            final File file = new File(pdfPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            if (svg != null) {
                for (int k = 0; k < svg.length; k++) {
                    final String picName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + ".png";
                    path[k] = request.getSession().getServletContext().getRealPath("/upload/" + picName);
                    imageList.add(path[k]);
                    SvgPngConverter.convertToPng(svg[k], path[k]);
                }
            }
        } catch (final IOException e) {
            e.printStackTrace();
        } catch (final TranscoderException e) {
            e.printStackTrace();
        }
        return imageList;
    }

    /**
     *
     * @param interval
     *            时间间隔
     * @param group
     *            主机组名称
     * @param topNum
     *            top数量
     * @return 筛选条件
     */
    public static String getCondition(final Integer interval, final String group, final Integer topNum,
        final String startDate,
        final String endDate) {
        final StringBuffer condition = new StringBuffer();
        if (interval == 24) {
            condition.append("最近24小时,");
        } else if (interval == 7) {
            condition.append("最近7天,");
        } else if (interval == 30) {
            condition.append("最近30天,");
        } else if (interval == 3) {
            condition.append("最近3个月,");
        } else if (interval == 12) {
            condition.append(startDate + "至" + endDate + " ");
        }
        if (group.equals("1 = 1")) {
            condition.append("所有主机组,");
        } else { //类似 g.name = 'Linux Server'
            condition.append(group.subSequence(group.indexOf("'") + 1, group.lastIndexOf("'")) + "组,");
        }

        condition.append("Top" + topNum);
        return condition.toString();
    }

    //获取当天的开始时间
    public static java.util.Date getDayBegin() {
        final Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    //获取本周的开始时间
    @SuppressWarnings("unused")
    public static Date getBeginDayOfWeek() {
        final Date date = new Date();
        if (date == null) {
            return null;
        }
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }

    //获取本月的开始时间
    public static Date getBeginDayOfMonth() {
        final Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return getDayStartTime(calendar.getTime());
    }

    //获取本年的开始时间
    public static java.util.Date getBeginDayOfYear() {
        final Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        // cal.set
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayStartTime(cal.getTime());
    }

    //获取今年是哪一年
    public static Integer getNowYear() {
        final Date date = new Date();
        final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    //获取本月是哪一月
    public static int getNowMonth() {
        final Date date = new Date();
        final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(final Date d) {
        final Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0,
            0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(final Date d) {
        final Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23,
            59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 数据过长，出现科学计数法，完全显示数据
     *
     * @param num
     *            数字
     * @return 字符串数据
     */
    public static String fullyDisplayNum(final double num) {
        final NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        return nf.format(num);
    }

    /**
     * 得到指定月的天数
     */
    public static int getMonthLastDay(final int year, final int month) {
        final Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        final int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    public static String getStartTime(final Integer interval) {
        final SimpleDateFormat myFmt = new SimpleDateFormat("yyyy-MM-dd");
        final Calendar startdate = Calendar.getInstance();
        startdate.setTime(new Date());
        if (interval == 24) { //最近24小时，最近7天，最近30天
            startdate.add(Calendar.DATE, -1);
        } else if (interval == 3) { //最近3个月

            startdate.add(Calendar.MONTH, -3);
        } else if (interval == 7) {
            startdate.add(Calendar.DATE, -7);
        } else if (interval == 30) {
            startdate.add(Calendar.MONTH, -1);
        }

        final Date deadLine = Calendar.getInstance().getTime();
        return myFmt.format(startdate.getTime());
    }
}
