package com.fxy.base;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;

import com.alibaba.fastjson.JSONException;
import com.fxy.BuildConfig;
import com.fxy.baselibrary.util.RxTimeTool;
import com.fxy.constant.SPCache;
import com.fxy.net.MyDialogCallback;
import com.fxy.net.Urls;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.Response;

import org.json.JSONObject;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Arrays;

public class CrashHandler implements UncaughtExceptionHandler {
    //系统默认的异常处理器
    private UncaughtExceptionHandler defaultCrashHandler;
    private static com.fxy.base.CrashHandler crashHandler = new com.fxy.base.CrashHandler();
    private Context mContext;
    //私有化构造函数
    private CrashHandler() {
    }
    //获取实例
    public static com.fxy.base.CrashHandler getInstance() {
        return crashHandler;
    }
    public void init(Context context) {
        mContext = context;
        defaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        //设置系统的默认异常处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        //把错误信息保存在sp中，然后在下次进入页面的时候再上传错误信息
        saveErrorInfo(throwable,thread);
        if (defaultCrashHandler != null) {
            //如果在自定义异常处理器之前，系统有自己的默认异常处理器的话，调用它来处理异常信息
            defaultCrashHandler.uncaughtException(thread, throwable);
        } else {
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
        }
    }
    public void sendError() {
        //先不发送
        try {
            SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
            String data = sp.getString("data", "");
            if (!data.isEmpty()) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("content",data);
                OkGo.<String>post(Urls.getServiceAddress(mContext) +Urls.RECORD_LOG).upJson(jsonObject.toString())
                        .execute(new MyDialogCallback(mContext, false, false) {
                            @Override
                            public void onSuccess(Response<String> response) {
                                try {
                                    SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
                                    sp.edit().putString("data", "").apply();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                //XLog.e(response.body());
                            }
                            @Override
                            public void onError(Response<String> response) {
                            }
                        });
            }
        } catch (JSONException | org.json.JSONException e) {
            e.printStackTrace();
        }
    }

    private void saveErrorInfo(Throwable throwable,Thread thread) {
        try {
            SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
            SPCache spCache = SPCache.getInstance(mContext);
            String accountInfo   = spCache.getUserName()+"("+spCache.getAccountName()+")";
            String stringBuffer = getAppInfo(mContext) +
                    "崩溃版本：" + BuildConfig.BUILD_TYPE + "\n\n" +
                    "崩溃时间：" + RxTimeTool.getCurTimeString() + "\n\n" +
                    "设备系统：" + Build.VERSION.RELEASE + "\n\n" +
                    "设备厂商：" + Build.MANUFACTURER + "\n\n" +
                    "设备型号：" + Build.MODEL + "\n\n" +
                    "账号信息：" + accountInfo + "\n\n" +
                    "崩溃原因：" + throwable.getMessage() + "\n\n" +
                    "详细信息：" + Arrays.toString(throwable.getStackTrace());
            sp.edit().putString("data", stringBuffer).apply();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取捕获异常的信息
     */
    private String collectExceptionInfo(Throwable ex) {
       try {
           Writer mWriter = new StringWriter();
           PrintWriter mPrintWriter = new PrintWriter(mWriter);
           ex.printStackTrace(mPrintWriter);
           ex.printStackTrace();
           Throwable mThrowable = ex.getCause();
           // 迭代栈队列把所有的异常信息写入writer中
           while (mThrowable != null) {
               mThrowable.printStackTrace(mPrintWriter);
               // 换行 每个个异常栈之间换行
               mPrintWriter.append("\r\n");
               mThrowable = mThrowable.getCause();
           }
           // 记得关闭
           mPrintWriter.close();
           return mWriter.toString();
       } catch (Exception e) {
           e.printStackTrace();
           return ex.getMessage();
       }
    }

    /**
     * 获取应用程序信息
     */
    public String getAppInfo(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            return "应用包名：" + packageInfo.packageName + "\n\n应用版本：" + packageInfo.versionName + "\n\n";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}
