package com.wdkl.lcd_board.helper;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import com.wdkl.ncs.android.component.welcome.activity.WelcomeActivity;
import com.wdkl.ncs.android.lib.base.BaseApplication;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class AppUpdateHelper {
    private final static String TAG = "AppUpdate";

    /**
     * 下载的APK文件绝对路径
     */
    public static final String FILE_APK_PATH = Environment.getExternalStorageDirectory() + "/lcd_board";
    /**
     * 下载的APK文件的文件名
     */
    public static final String FILE_APK_NAME = "lcd_board.apk";

    public static void updateApp(Context context, UpdateCallBack callBack) {
        if (checkApkExit(context)) {
            Log.d(TAG, "文件存在");
        } else {
            Log.d(TAG, "文件不存在");
            if (callBack != null) {
                callBack.onFailed();
            }
            return;
        }


        String path = FILE_APK_PATH + "/" + FILE_APK_NAME;
        if (rootSilenceInstall(path)) {
            Log.d(TAG, "安装成功");
            if (callBack != null) {
                callBack.onSuccess();
            }
        } else {
            Log.d(TAG, "安装失败");
            if (callBack != null) {
                callBack.onFailed();
            }
        }
    }

    private static boolean checkApkExit(Context context) {
        File file = new File(FILE_APK_PATH + "/" + FILE_APK_NAME);
        return file.exists();
    }

    private static boolean checkApkAvailable(Context context, String path) {
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo info = pm.getPackageArchiveInfo(path, 0);
            ApplicationInfo applicationInfo = info.applicationInfo;
            String newPkg = applicationInfo.packageName;
            String curPkg = context.getPackageName();
            Log.d(TAG, "new package: " + newPkg + ", cur package: " + curPkg);
            if (curPkg.equals(newPkg)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public static boolean silentInstall(Context context, String apkPath) {
        PackageManager packageManager = context.getPackageManager();
        Class pmClz = packageManager.getClass();
        try {
            if (Build.VERSION.SDK_INT >= 21) {
                Log.d(TAG, "apk path: " + apkPath);
                Class aClass = Class.forName("android.app.PackageInstallObserver");
                Constructor constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                Object installObserver = constructor.newInstance();
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), installObserver, 2, null);
            } else {
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, null);
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return false;
    }

    public static boolean installApp(String packageName, String apkPath) {
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder errorMsg = new StringBuilder();
        Log.e(TAG, "install package: " + packageName + ", apkPath: " + apkPath);
        try {
            process = new ProcessBuilder("pm", "install", "-i", packageName, "-r", apkPath).start();
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String s;
            while ((s = successResult.readLine()) != null) {
                successMsg.append(s);
            }
            while ((s = errorResult.readLine()) != null) {
                errorMsg.append(s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
        Log.e(TAG, "" + errorMsg.toString());
        //如果含有“success”认为安装成功
        return successMsg.toString().equalsIgnoreCase("success");
    }

    public static boolean rootSilenceInstall(String path) {
        Process process;
        PrintWriter printWriter;
        try {
            process = Runtime.getRuntime().exec("su");
            printWriter = new PrintWriter(process.getOutputStream());
            printWriter.println("pm install -r " + path);
            printWriter.flush();
            printWriter.close();

            Intent intent = new Intent(BaseApplication.appContext, WelcomeActivity.class);
            PendingIntent restartIntent = PendingIntent.getActivity(BaseApplication.appContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
            AlarmManager mgr = (AlarmManager) BaseApplication.appContext.getSystemService(Context.ALARM_SERVICE);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
                mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 45000, restartIntent);

            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
                mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 45000, restartIntent);
            }

            int res = process.waitFor();
            Log.e(TAG, "silent install res: " + res);
            if (res == 0) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            Log.e(TAG, "rootSilenceInstall e:" + e.getMessage());
            return false;
        }
    }

    public static void reboot(Context context) {
        if (Build.MODEL.equals("rk3128")) {
            try {
                Intent intent = new Intent(Intent.ACTION_REBOOT);
                intent.putExtra("nowait", 1);
                intent.putExtra("interval", 1);
                intent.putExtra("window", 0);
                context.sendBroadcast(intent);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (Build.MODEL.equals("rk3288")) {
            Process process;
            PrintWriter printWriter;
            try {
                process = Runtime.getRuntime().exec("su");
                printWriter = new PrintWriter(process.getOutputStream());
                printWriter.println("reboot");
                printWriter.flush();
                printWriter.close();
                process.waitFor();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void rebootDevice() {
        if (Build.BOARD.equals("rk30sdk")) {
            reboot(BaseApplication.appContext);
        } else {
            Intent intent = new Intent("android.intent.action.reboot");
            BaseApplication.appContext.sendBroadcast(intent);
        }
    }

    public static void restartApp(Context context) {
        //重新启动app
        Intent mStartActivity = new Intent(context.getApplicationContext(), WelcomeActivity.class);
        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        int mPendingIntentId = 123456;
        PendingIntent mPendingIntent = PendingIntent.getActivity(context.getApplicationContext(), mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager mgr = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, mPendingIntent);

        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(0);
    }

    public interface UpdateCallBack {
        void onFailed();
        void onSuccess();
    }
}
