package com.sobot.utils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * @Description: 日志工具类
 * @Author: znw
 * @Date: 2021/7/15 下午5:46
 * @Version: 1.0
 */
public class SobotLogUtils {

    // 日志显示开关
    public static boolean isDebug = false;
    // 日志本地保存开关
    public static boolean isCache = true;
    // 日志缓存各级别开关
    public static boolean allowD = false;
    public static boolean allowE = false;
    public static boolean allowI = false;
    public static boolean allowV = false;
    public static boolean allowW = false;
    public static boolean allowWtf = false;
    // 存储时长 单位 ：天
    public static int maxTime = 3;
    // 项目名称
    private static String mAppName = "sobot_chat";
    // 日志文件路径
    public static String path = null;
    // 日志文件夹路径
    private static File file = null;

    public static final String LOGTYPE_ERROE = "1";
    public static final String LOGTYPE_EXCEPTION = "2";
    public static final String LOGTYPE_INFO = "3";

    private SobotLogUtils() {
    }

    /**
     * 初始化
     *
     * @param context
     */
    public static void init(Context context) {
        // 获取appname
        PackageManager packageManager = context.getApplicationContext()
                .getPackageManager();
        try {
            ApplicationInfo applicationInfo = packageManager
                    .getApplicationInfo(context.getPackageName(), 0);
            mAppName = (String) packageManager
                    .getApplicationLabel(applicationInfo);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        // 获取日志缓存路径
        if (isCache) {
            setSaveDir(SobotSDCardUtils.getSDCardRootPath(context));
        }
    }

    /**
     * 设置日志保存的路径 默认为：app名字/sobot/sobot_log.txt
     *
     * @param dir
     */
    public static void setSaveDir(String dir) {
        String str = dir + File.separator + mAppName + File.separator + "sobot";
        SobotLogUtils.path = str + File.separator + "sobot_log.txt";
        SobotLogUtils.file = new File(str);
    }

    /**
     * 日志显示设置
     *
     * @param isShowLog true 显示日志信息 默认false不显示
     */
    public static void setShowDebug(Boolean isShowLog) {
        if (isShowLog) {
            SobotLogUtils.isDebug = true;
            SobotLogUtils.allowI = true;
            SobotLogUtils.allowE = true;
            SobotLogUtils.allowD = true;
        } else {
            SobotLogUtils.isDebug = false;
            SobotLogUtils.allowI = false;
            SobotLogUtils.allowE = false;
            SobotLogUtils.allowD = true;
        }
    }


    /**
     * 设置日志缓存时间
     */
    public static void setCacheTime(int cacheTime) {
        if (cacheTime < 0) {
            return;
        }
        SobotLogUtils.maxTime = cacheTime;
    }

    /**
     * 获取日志过滤 tag
     *
     * @return
     */
    public static String generateTag() {
        return "sobot_log";
    }

    /**
     * 设置日志缓存
     */
    public static void setIsCache(boolean isCache) {
        SobotLogUtils.isCache = isCache;
    }

    /**
     * 保存日志文件到本地
     */
    public static void saveToLocal(String content,
                                   Throwable tr) {
        if (!TextUtils.isEmpty(SobotLogUtils.path)) {
            PrintWriter pw = null;
            if (!file.exists()) {
                file.mkdirs();
            }
            try {
                pw = new PrintWriter(new OutputStreamWriter(
                        new FileOutputStream(SobotLogUtils.path, true), "utf-8"));
                pw.println(TextUtils.isEmpty(content) ? "" : content);
                pw.flush();
                if (tr != null) {
                    tr.printStackTrace(pw);
                }
                pw.flush();
            } catch (Exception e) {
            } finally {
                if (pw != null) {
                    pw.close();
                }
            }
            checkAndclearLog();
        }
    }

    /**
     * 如果日志超过缓存时间，清理
     */
    public static void checkAndclearLog() {
        if (SobotLogUtils.maxTime < 0) {
            return;
        }
        try {
            int currentTime = Integer.parseInt(getCurrentTime("yyyyMMdd"));
            File[] tempList = SobotLogUtils.file.listFiles();
            if (tempList != null && tempList.length > 0) {
                for (int i = 0; i < tempList.length; i++) {
                    if (tempList[i].isFile()) {
                        String tempName = tempList[i].getName().split("_")[1];
                        Integer tempDate = Integer.valueOf(tempName);
                        if ((currentTime - tempDate) >= maxTime) {
                            tempList[i].delete();
                        }
                    }
                }
            }
        } catch (Exception e) {

        }
    }

    /**
     * 清理日志
     */
    public static synchronized void clearAllLog() {
        try {
            File[] tempList = SobotLogUtils.file.listFiles();
            if (tempList != null && tempList.length > 0) {
                for (int i = 0; i < tempList.length; i++) {
                    if (tempList[i].isFile()) {
                        tempList[i].delete();
                    }
                }
            }
        } catch (Exception e) {

        }
    }

    /**
     * 读取日志内容
     */
    public static synchronized String getLogContent() {
        File file = new File(SobotLogUtils.path);
        if (!file.exists()) {
            return null;
        }
        JSONArray jsonObjArr = new JSONArray();
        BufferedReader br = null;
        try {
            String str = null;
            br = new BufferedReader(new FileReader(file));
            while ((str = br.readLine()) != null) {
                JSONObject jsonObject = new JSONObject(str);
                jsonObjArr.put(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return jsonObjArr.toString();
    }

    /*
     * 获取日志文件的路径
     */
    public static String getLogFilePath() {
        return SobotLogUtils.path;
    }

    /*
     * 获取日志文件夹路径
     */
    public static File getLogFile() {
        return SobotLogUtils.file;
    }

    /**
     * 根据日期获取日志文件的路径
     *
     * @param date 日期（yyyyMMdd） 20160312
     */
    public static String getLogFileByDate(String date) {
        if (TextUtils.isEmpty(date)) {
            return null;
        }

        File file2 = new File(SobotLogUtils.file, mAppName + "_"
                + date + "_log.txt");
        if (file2.exists()) {
            return file2.getAbsolutePath();
        } else {
            return null;
        }
    }

    /**
     * 获取时间并且格式化
     */
    private static String getCurrentTime(String format) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        String currentTime = dateFormat.format(date);
        return currentTime;
    }

    public static void d(String content) {
        if (isDebug && allowD) {
            String tag = generateTag();
            Log.d(tag, content);
        }
    }

    public static void d(String content, Throwable tr) {
        if (isDebug && allowD) {
            String tag = generateTag();
            Log.d(tag, content, tr);
        }
    }

    public static void e(String content) {
        if (isDebug && allowE) {
            String tag = generateTag();
            Log.e(tag, content);
        }
    }

    public static void e(String content, Throwable tr) {
        if (isDebug && allowE) {
            String tag = generateTag();
            Log.e(tag, content, tr);
        }
    }

    //分段打印日志每次最大长度
    private static final int MAX_LENGTH = 3 * 1024;

    public static void i(String content) {
        if (isDebug && allowI) {
            String tag = generateTag();
            //采取分段打印日志的方法：当长度超过4000时，我们就来分段截取打印
            if (content.length() > MAX_LENGTH) {
                String part = content.substring(0, MAX_LENGTH);
                Log.i(tag + "分段打印开始", part);

                part = content.substring(MAX_LENGTH, content.length());
                if ((content.length() - MAX_LENGTH) > MAX_LENGTH) {
                    i(part);
                } else {
                    Log.i(tag + "分段打印结束", part);
                }
            } else {
                //直接打印
                Log.i(tag, content);
            }
        }
    }

    public static void i(String content, Throwable tr) {
        if (isDebug && allowI) {
            String tag = generateTag();
            Log.i(tag, content, tr);
        }
    }

    public static void v(String content) {
        if (isDebug && allowV) {
            String tag = generateTag();
            Log.v(tag, content);
        }
    }

    public static void v(String content, Throwable tr) {
        if (isDebug && allowV) {
            String tag = generateTag();
            Log.v(tag, content, tr);
        }
    }

    public static void w(String content) {
        if (isDebug && allowW) {
            String tag = generateTag();
            Log.w(tag, content);
        }
    }

    public static void w(String content, Throwable tr) {
        if (isDebug && allowW) {
            String tag = generateTag();
            Log.w(tag, content, tr);
        }
    }

    public static void w(Throwable tr) {
        if (isDebug && allowW) {
            String tag = generateTag();
            Log.w(tag, tr);
        }
    }

    public static void wtf(String content) {
        if (isDebug && allowWtf) {
            String tag = generateTag();
            Log.wtf(tag, content);
        }
    }

    public static void wtf(String content, Throwable tr) {
        if (isDebug && allowWtf) {
            String tag = generateTag();
            Log.wtf(tag, content, tr);
        }
    }

    public static void wtf(Throwable tr) {
        if (isDebug && allowWtf) {
            String tag = generateTag();
            Log.wtf(tag, tr);
        }
    }

    /**
     * 向本地日志文件写内容
     */
    public static synchronized void writeLogToFile(Map<String, String> map) {
        String time = getCurrentTime("yyyy-MM-dd HH:mm:ss");
        map.put("type", LOGTYPE_INFO);
        map.put("time", time);
        String json = mapToJson(map);
        saveToLocal(json, null);
    }

    /**
     * 向本地日志文件写内容
     *
     * @param map
     * @param logtype
     */
    public static synchronized void writeLogToFile(Map<String, String> map, String logtype) {
        String time = getCurrentTime("yyyy-MM-dd HH:mm:ss");
        if (map == null) {
            return;
        }
        map.put("type", logtype);
        map.put("time", time);
        String json = mapToJson(map);
        saveToLocal(json, null);
    }

    public static String mapToJson(Map<String, String> map) {
        if (map != null && map.size() > 0) {
            JSONObject a = new JSONObject(map);
            return a.toString();
        }
        return "";
    }

}