package com.emato.ich.update;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class APKAutoUpdate {

    private static final String TAG = APKAutoUpdate.class.getName();

    /**
     * 适配android9的安装方法。
     * 全部替换安装
     * @return
     */
    public static Boolean installApk(Context mContext, String apkFilePath, OnInstallListener listener) {
        File apkFile = new File(apkFilePath);
        if (!apkFile.exists()) {
            return null;
        }

        PackageInfo packageInfo = mContext.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
        if (packageInfo != null) {
            String packageName = packageInfo.packageName;
            int versionCode = packageInfo.versionCode;
            String versionName = packageInfo.versionName;
            Log.d(TAG, "packageName=" + packageName + ", versionCode=" + versionCode + ", versionName=" + versionName);
        }

        PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams sessionParams
                = new PackageInstaller.SessionParams(PackageInstaller
                .SessionParams.MODE_FULL_INSTALL);
        sessionParams.setSize(apkFile.length());

        int mSessionId = 0;
        try {
            mSessionId = packageInstaller.createSession(sessionParams);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "sessionId---->" + mSessionId);
        if (mSessionId != -1) {
            boolean copySuccess = onTransformApkFile(mContext, apkFilePath, mSessionId, listener);
            Log.d(TAG, "copySuccess---->" + copySuccess);
            if (copySuccess) {
                execInstallAPP(mContext, mSessionId, listener);
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * 通过文件流传输apk
     *
     * @param apkFilePath
     * @return
     */
    private static boolean onTransformApkFile(Context mContext, String apkFilePath, int mSessionId, OnInstallListener listener) {
        InputStream in = null;
        OutputStream out = null;
        PackageInstaller.Session session = null;
        boolean success = false;
        try {
            File apkFile = new File(apkFilePath);
            session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
            out = session.openWrite("base.apk", 0, apkFile.length());
            in = new FileInputStream(apkFile);
            int total = 0, c;
            byte[] buffer = new byte[1024 * 1024];
            while ((c = in.read(buffer)) != -1) {
                total += c;
                out.write(buffer, 0, c);
            }
            session.fsync(out);
            Log.d(TAG, "streamed " + total + " bytes");
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
            listener.onInstallException(e);
        } finally {
            if (null != session) {
                session.close();
            }
            try {
                if (null != out) {
                    out.close();
                }
                if (null != in) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                listener.onInstallException(e);
            }
        }
        return success;
    }
    /**
     * 执行安装并通知安装结果
     *
     */
    private static void execInstallAPP(Context mContext, int mSessionId, OnInstallListener listener) {
        PackageInstaller.Session session = null;
        try {
            session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
            Intent intent = new Intent(mContext, InstallResultReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
                    1, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            session.commit(pendingIntent.getIntentSender());
            listener.onInstallSuccess();
        } catch (IOException e) {
            e.printStackTrace();
            listener.onInstallException(e);
        } finally {
            if (null != session) {
                session.close();
            }
        }
    }


}
