package com.kfzs.duanduan.utils;

import android.annotation.SuppressLint;
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.content.pm.Signature;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Base64;

import com.kfzs.duanduan.KFZSApp;
import com.sheep.jiuyan.samllsheep.R;
import com.kfzs.duanduan.bean.CompareResult;
import com.sheep.jiuyan.samllsheep.SheepApp;
import com.sheep.jiuyan.samllsheep.utils.G;
import com.sheep.jiuyan.samllsheep.utils.PackageUtil;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * apk helper
 * <p>
 * Created by HooRang on 2017/2/23.
 */
public class ApkUtils {

    private Map<String, PackageInfo> installedApkContainer;

    private static ApkUtils apkUtil;

    public static ApkUtils getInstance() {
        if (null == apkUtil) {
            apkUtil = new ApkUtils();
            apkUtil.setInstalledApkContainer();
        }
        return apkUtil;

    }


    public void clear() {
        installedApkContainer = null;

    }
    private void setInstalledApkContainer() {
        installedApkContainer = KFZSApp.getInstance().loadPackagesInfoRealTime();

    }

    /**
     * get UnInstallApkPackageName
     *
     * @param context Context
     * @param apkPath apkPath
     * @return apk PackageName
     */
    public static String getUnInstallApkPackageName(Context context, String apkPath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
        if (info != null) {
            ApplicationInfo appInfo = info.applicationInfo;
            if (appInfo != null) {
                return appInfo.packageName;
            }
        }
        return null;
    }

    /**
     * install an apk bu apkPath
     *
     * @param context Context
     * @param apkPath apkPath
     */
    public static final void installApk(Context context, String apkPath) {
        if(TextUtils.isEmpty(apkPath)){
//            G.showToast(R.string.unknown_error);
            return;
        }

        PackageUtil.installApk(context, apkPath);

        /*
          设置包名
         */
        SheepApp.getInstance()
                .setPackgeName(
                        getUnInstallApkPackageName(context, apkPath));
    }


    /**
     * get alll installed apks
     *
     * @param context
     * @return
     */
    public static Map<String, PackageInfo> getInstalledApks(Context context) {

        Map<String, PackageInfo> apkContainer = new HashMap<>();
        if (context == null) {

            return apkContainer;
        }

        List<PackageInfo> installPkgs = context.getPackageManager().getInstalledPackages(0);
        for (PackageInfo apk : installPkgs) {
            apkContainer.put(apk.packageName, apk);
        }
        return apkContainer;
    }




    /**
     * Open a application by packagename
     *
     * @param context
     * @param pkgName
     */
    public static void openApplication(Context context, String pkgName) {

        Intent intent = context.getPackageManager().getLaunchIntentForPackage(pkgName);
        context.startActivity(intent);
    }


    /**
     * @param packageName
     * @return
     */
    public boolean isPkgInstalled(String packageName) {

        if (null == installedApkContainer || installedApkContainer.isEmpty()) {
            setInstalledApkContainer();
        }

        return installedApkContainer.containsKey(packageName);
    }

    public boolean isPkgInstalledRealTime(String packageName){
        return KFZSApp.getInstance().loadPackagesInfoRealTime().containsKey(packageName);
    }

    /**
     * 是否需要更新，只有安装后，且安装的版本小于versionCode，才返回true
     * @param packageName
     * @param versionCode
     * @return
     */
    public boolean isPkgNeedUpdateRealTime(String packageName, int versionCode){
        Map<String, PackageInfo> infos = KFZSApp.getInstance().loadPackagesInfoRealTime();
        if(infos.containsKey(packageName)){
            PackageInfo info = infos.get(packageName);
            return info != null && info.versionCode < versionCode;
        } else {
            return false;
        }
    }

    /**
     * Has the apk need update that's installed already
     *
     * @param packageName
     * @param versionCode
     * @return
     */
    public boolean isPkgNeedUpdate(String packageName, int versionCode) {

        if (null == installedApkContainer || installedApkContainer.isEmpty()) {
            setInstalledApkContainer();
        }
        PackageInfo pkg = installedApkContainer.get(packageName);

        return pkg.versionCode < versionCode ? true : false;

    }

    /**
     * compare installed package's versionCode
     * <p>
     * 0  ： euqal
     * 1  : gt
     * -1  : lt
     *
     * @param packageName
     * @param versionCode
     * @return
     */
    public int comparePkgVersionCode(String packageName, int versionCode) {
        if (null == installedApkContainer || installedApkContainer.isEmpty()) {
            setInstalledApkContainer();
        }
        PackageInfo pkg = installedApkContainer.get(packageName);
        if(null == pkg){
            return CompareResult.EQUALS;
        }
        if (pkg.versionCode == versionCode) {
            return CompareResult.EQUALS;
        } else if (pkg.versionCode < versionCode) {
            return CompareResult.GT;
        } else {
            return CompareResult.LT;
        }
    }


    /**
     * Get application's icon by packagename
     *
     * @param context
     * @param packageName
     * @return
     */
    public Drawable getIconByPackageName(Context context, String packageName) {
        if (null == installedApkContainer || installedApkContainer.isEmpty()) {
            setInstalledApkContainer();
        }
        return installedApkContainer.get(packageName).applicationInfo.loadIcon(context.getPackageManager());
    }

    public Drawable getAppIconOnce(Context context, String packageName) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            return packageInfo.applicationInfo.loadIcon(packageManager);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    public String getAppLabelOnce(Context context, String packageName) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            return packageInfo.applicationInfo.loadLabel(packageManager).toString();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * Get application's appname by packagename
     *
     * @param context
     * @param packageName
     * @return
     */
    public String getAppNameByPackageName(Context context, String packageName) {
        if (null == installedApkContainer || installedApkContainer.isEmpty()) {
            setInstalledApkContainer();
        }
        return installedApkContainer.get(packageName).applicationInfo.loadLabel(context.getPackageManager()).toString();
    }

    public static String getApkSignatureByPackageName(Context ctx, String packageName) {
        if (TextUtils.isEmpty(packageName)) {
            return null;
        }
        String res = null;
        try {
            @SuppressLint("PackageManagerGetSignatures") PackageInfo info = ctx.getPackageManager().getPackageInfo(
                    packageName, PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                res = Base64.encodeToString(md.digest(), Base64.DEFAULT);
            }
        } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return res;
    }


    public static String getCurrentPkgVersionName(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            return pi.versionName;
        } catch (Exception e) {
            return "0.0.0";
        }
    }
    public static PackageInfo getPackageInfo(String packageName) {
        try {
            PackageManager pm = SheepApp.getInstance().getPackageManager();
            PackageInfo pi = pm.getPackageInfo(packageName, 0);
            return pi;
        } catch (Exception e) {
            return null;
        }
    }


    public static int getCurrentPkgVersionCode(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            return pi.versionCode;
        } catch (Exception e) {
            return 0;
        }
    }


    public static void invokeBroswer(Context context ,String targetUrl){
        Uri uri = Uri.parse(targetUrl);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(uri);
        context.startActivity(intent);
    }

    public static String getUUID() {
        return UUID.randomUUID().toString();
    }

}
