package com.sheep.gamegroup.module.plugin.util;

import android.content.Context;

import com.alibaba.fastjson.JSONObject;
import com.didi.virtualapk.PluginManager;
import com.sheep.gamegroup.model.entity.BaseMessage;
import com.sheep.gamegroup.model.util.SheepSubscriber;
import com.sheep.gamegroup.module.plugin.model.ClientPackage;
import com.sheep.gamegroup.module.plugin.model.Plugin;
import com.sheep.gamegroup.util.DataUtil;
import com.sheep.gamegroup.util.DownloadUtil;
import com.sheep.gamegroup.util.ListUtil;
import com.sheep.gamegroup.util.LogUtil;
import com.sheep.gamegroup.util.Md5Util;
import com.sheep.gamegroup.util.TestUtil;
import com.sheep.jiuyan.samllsheep.BuildConfig;
import com.sheep.jiuyan.samllsheep.SheepApp;
import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
import com.sheep.jiuyan.samllsheep.utils.G;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;

import org.afinal.simplecache.ApiKey;

import java.io.File;
import java.util.Locale;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;

/**
 * Created by realicing on 2018/12/6.
 * realicing@sina.com
 */
public class PluginUtil {

//    public static final String[] ABIS = { "armeabi-v7a", "arm64-v8a", "x86", "mips", "x86_64", "armeabi"};
    public static final String[] ABIS = { "armeabi-v7a", "arm64-v8a", "x86"};
    public static Observable<Plugin> startPlugin(Plugin plugin) {
        return Observable.create((ObservableOnSubscribe<Plugin>) emitter -> {
//            if(TextUtils.equals(getCPU_ABI(), "x86") && TestUtil.isSheep()){
//                emitter.onError(new Throwable("暂不支持该设备"));
//                return;
//            }
            int downloadPluginState = DataUtil.getAsInt(getDownloadPluginKey(plugin), DownloadUtil.STATUS_INIT);
            switch (downloadPluginState){
                case DownloadUtil.STATUS_FINISH:
                    if (PluginManager.getInstance(SheepApp.getInstance()).getLoadedPlugin(plugin.getPackageName()) == null) {
//                String cpuAbi = getCPU_ABI();
//                String pluginPath = String.format(Locale.CHINA, "%s/media_%s.apk", ClassFileHelper.DIR, cpuAbi);
                        String pluginPath = ClassFileHelper.DIR + "/media_release.apk";
//                LogUtil.println(PluginUtil.class.getSimpleName(), "CPU_ABI =", cpuAbi, "pluginPath =", pluginPath);
                        File file = new File(pluginPath);
                        boolean isUserTestFile = TestUtil.isTest() && file.exists();
                        LogUtil.println("startPlugin", isUserTestFile);
                        File pluginFile = isUserTestFile ? file : getFile(plugin);
                        if(!pluginFile.exists()){
                            emitter.onError(new Throwable("更新数据中，请稍候再试"));
                            return;
                        }
                        try {
                            PluginManager.getInstance(SheepApp.getInstance()).loadPlugin(pluginFile);
                            emitter.onNext(plugin);
                        } catch (Exception e) {
                            e.printStackTrace();
                            emitter.onError(e);
                        }
                    } else {
                        emitter.onNext(plugin);
                    }
                    break;
                case DownloadUtil.STATUS_ING:
                    emitter.onError(new Throwable("更新数据中，请稍候再试"));
                    break;
                case DownloadUtil.STATUS_INIT:
                    initPlugin();
                    emitter.onError(new Throwable("更新数据中，请稍候再试"));
                    break;
                case DownloadUtil.STATUS_FAIL:
                default:
                    emitter.onError(new Throwable("敬请期待"));
                    break;
            }
        }).subscribeOn(Schedulers.io());
    }

    /**
     * 根据系统的cpu_abi来获取最接近的cpu_abi
     * @return
     */
    public static String getCPU_ABI() {
        String CPU_ABI = android.os.Build.CPU_ABI;
        if(!ListUtil.contains(ABIS, CPU_ABI)){
            LogUtil.println(PluginUtil.class.getSimpleName(), "not contains", CPU_ABI);
            CPU_ABI = ABIS[0];
        }
        return CPU_ABI;
//        return "x86";
    }


    //初始化插件
    public static void initPlugin() {
        Plugin plugin = Plugin.media;
        String packageName = plugin.getPackageName();
        String type = PluginUtil.getCPU_ABI();
        int versionCode = BuildConfig.VERSION_CODE;
        SheepApp.getInstance().getNetComponent().getApiService().getPackageVersion(packageName, type, versionCode)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SheepSubscriber<BaseMessage>(SheepApp.getInstance()) {
                    @Override
                    public void onNext(BaseMessage baseMessage) {
                        LogUtil.println("initPlugin", JSONObject.toJSONString(baseMessage.getData()));
                        ClientPackage result = baseMessage.getData(ClientPackage.class);
                        if(result != null && result.getMd_5() != null){
                            String key = ApiKey.getPackageVersion(packageName, type, versionCode);
                            File file = getFile(key);
                            if(file.exists()){
                                if(Md5Util.checkMD5(result.getMd_5(), file)){
                                    DataUtil.putAsInt(getDownloadPluginKey(plugin), DownloadUtil.STATUS_FINISH);
                                    return;
                                }
                            }
                            downloadPlugin(result.getDowload_url(), plugin);
                        }
//                        boolean isNewData = DataUtil.getInstance().isNewData(key);
//                        if(isNewData){
//
//                        }
                    }

                    @Override
                    public void onError(BaseMessage baseMessage) {
                        if(TestUtil.isDev()) G.showToast(baseMessage);
                    }
                });
    }

    private static void downloadPlugin(String dowload_url, Plugin plugin) {
        DataUtil.putAsInt(getDownloadPluginKey(plugin), DownloadUtil.STATUS_ING);
        OkHttpUtils.get().url(dowload_url).build().execute(new FileCallBack(getDirPath(), getFileName(plugin)) {
            @Override
            public void inProgress(float progress, long total, int id) {
                LogUtil.println("downloadPlugin", dowload_url, String.format(Locale.CHINA, "%d%%", Math.round(progress * 100)));
            }

            @Override
            public void onError(Call call, Exception e, int id) {
                LogUtil.println("downloadPlugin", dowload_url, "下载失败");
                DataUtil.putAsInt(getDownloadPluginKey(plugin), DownloadUtil.STATUS_FAIL);
            }

            @Override
            public void onResponse(File response, int id) {
                LogUtil.println("downloadPlugin", dowload_url, "下载完成");
                DataUtil.putAsInt(getDownloadPluginKey(plugin), DownloadUtil.STATUS_FINISH);
            }
        });
    }

    public static File getDir() {
        return SheepApp.getInstance().getDir("plugin", Context.MODE_PRIVATE);
    }

    public static String getDirPath() {
        return SheepApp.getInstance().getDir("plugin", Context.MODE_PRIVATE).getPath();
    }
    public static File getFile(Plugin plugin) {
        String key = getKey(plugin);
        return getFile(key);
    }
    public static String getDownloadPluginKey(Plugin plugin){
        return "download_plugin_" + getKey(plugin);
    }
    public static String getKey(Plugin plugin){
        String packageName = plugin.getPackageName();
        String type = PluginUtil.getCPU_ABI();
        int versionCode = BuildConfig.VERSION_CODE;
        return ApiKey.getPackageVersion(packageName, type, versionCode);
    }
    public static String getFileName(Plugin plugin) {
        String key = getKey(plugin);
        return key.hashCode()+".apk";
    }
    public static File getFile(String key) {
        return new File(getDir(), key.hashCode()+".apk");
    }
}
