package com.wdkl.app.ncs.callingbed.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 java.io.File;
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() + "/CallingBed";
    /**
     * 下载的APK文件的文件名
     */
    public static final String FILE_APK_NAME = "CallingBedAPK.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 (installApp(context.getPackageName(), path)) {
        if (rootSilenceInstall(path)) {
            Log.d(TAG, "安装成功");
            if (callBack != null) {
                callBack.onSuccess();
            }
        } else {
            Log.d(TAG, "安装失败");
            if (callBack != null) {
                callBack.onFailed();
            }
        }

        /*if (silentInstall(context, path)) {
            Log.d(TAG, "app 安装成功");
            if (callBack != null) {
                callBack.onSuccess();
            }
        }*/
    }

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

        /*if (!checkApkAvailable(context, DownloadUtil.FILE_APK_PATH + "/" + DownloadUtil.FILE_APK_NAME)) {
            ToastUtil.showToast("apk文件不匹配，升级失败！");
            return;
        }*/


        if (silentInstall(context, FILE_APK_PATH + "/" + FILE_APK_NAME)) {
            Log.d(TAG, "app 安装成功");
        }
    }

    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) {
                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 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();
            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) {
        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();
        }

        SerialPortHelper.resetDevice();
    }

    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() + 1500, mPendingIntent);

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


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