/*
 * Tencent is pleased to support the open source community by making Tinker available.
 *
 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

package basic.app;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Environment;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.sohuott.vod.security.ServiceGuardReciver;
import com.tencent.tinker.anno.DefaultLifeCycle;
import com.tencent.tinker.lib.tinker.TinkerInstaller;
import com.tencent.tinker.loader.app.DefaultApplicationLike;
import com.tencent.tinker.loader.shareutil.ShareConstants;
import com.wasu.authsdk.AuthConfig;
import com.wasu.authsdk.AuthSDK;
import com.wasu.authsdk.IAuthInterface;
import com.wasu.comp.ad.WasuAdEngine;
import com.wasu.cs.model.ConfigData;
import com.wasu.cs.module.AuthMiguModule;
import com.wasu.cs.module.CornerMarkModule;
import com.wasu.cs.module.ScreenSaverModule;
import com.wasu.cs.module.WasuCacheModule;
import com.wasu.decode.WatchDog;
import com.wasu.frescoimagefetchermodule.FrescoImageFetcherModule;
import com.wasu.module.datafetch.DataFetchListener;
import com.wasu.module.datafetch.DataFetchModule;
import com.wasu.module.db.DBManage;
import com.wasu.module.http.HttpRequestModule;
import com.wasu.module.log.LogLevel;
import com.wasu.module.log.WLog;
import com.wasu.module.msgqueue.MsgQueueModule;
import com.wasu.statistics.WasuStatistics;

import org.json.JSONObject;

import basic.BuilderTypeManager.BuildType;
import basic.BuilderTypeManager.BuilderTypeManager;
import basic.ad.model.WasuAdManager;
import basic.db.listeners.AbsWasuDbListener;
import basic.db.listeners.SaveFavoriteTimeListener;
import basic.db.model.DBProgramChildFavorite;
import basic.db.model.DBProgramFavorite;
import basic.db.model.DBProgramHistory;
import basic.debug.BuLogLever;
import basic.debug.DebugUtil;
import basic.debug.EmptyLogLever;
import basic.update.present.UpdatePresent;
import cn.com.wasu.main.AppUtil;
import cn.com.wasu.main.BuildConfig;
import cn.com.wasu.main.Common;

/**
 * As Application, all its direct reference class should be in the main dex.
 * <p>
 * We use tinker-android-anno to make sure all your classes can be patched.
 * <p>
 * application: if it is start with '.', we will add SampleApplicationLifeCycle's package name
 * <p>
 * flags:
 * TINKER_ENABLE_ALL: support dex, lib and resource
 * TINKER_DEX_MASK: just support dex
 * TINKER_NATIVE_LIBRARY_MASK: just support lib
 * TINKER_RESOURCE_MASK: just support resource
 * <p>
 * loaderClass: define the tinker loader class, we can just use the default TinkerLoader
 * <p>
 * loadVerifyFlag: whether check files' md5 on the load time, defualt it is false.
 * <p>
 * Created by zhangshaowen on 16/3/17.
 */
@SuppressWarnings("unused")
@DefaultLifeCycle(application = "basic.app.TvApp",
        flags = ShareConstants.TINKER_ENABLE_ALL,
        loadVerifyFlag = false)
public class TvAppLike extends DefaultApplicationLike {
    private static final String TAG = "TvAppLike";
    public TvAppLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag,
                     long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
    }

    /**
     * install multiDex before install tinker
     * so we don't need to put the tinker lib classes in the main dex
     *
     * @param base
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);

    }

    public static final String EXIT_ACTION = "com.wasu.action.exitapp";
    private static ConfigData configData;
    /**
     * 是否为高配置的设备
     */
    public static boolean isHighDevice = true;
    /**
     * 全局的上下文.
     */
    private static Context mContext = null;
    /**
     * 应用市场版本的包名
     */
    private static final String WASU_PROCESS_NAME_MARKET = "cn.com.wasu.main";
    /**
     * 厂家定制的包名
     */
    private static final String WASU_PROCESS_NAME_FACTORY = "cn.com.wasu.tvsp";

    private static BroadcastReceiver mAppReceiver = null;

    /**
     * 弹出多个详情页容易导致oom，所以方式是最多只能弹出3层界面，后续记录ID，动态加载 上一个层级
     **/
    public static int MAX_LAYER = 3;

    private static Application instance = null;

    public static Application getInstance() {
        if (instance == null) {
            throw new IllegalStateException("Not yet initialized");
        }
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        instance = getApplication();

        Log.d(TAG, "onCreate() called");

        TinkerInstaller.install(this);

        mContext = getApplication().getApplicationContext();

        boolean apkDebugAble = DebugUtil.isApkDebugable(mContext);
        //log 管理 [emptyLogLever 意味着关闭log]
        if (apkDebugAble) {
            WLog.getInstance().init(LogLevel.VERBOSE, new BuLogLever());
        } else {
            WLog.getInstance().init(LogLevel.VERBOSE, new EmptyLogLever());
        }

//		//sohu初始化
//		ServiceGuardReciver.checkAndRestartLocaleServer(getApplicationContext());

        boolean isWasuPorcess = isWasuProcess(mContext);

        if (isWasuPorcess) {
            //here we begin to init wasu application

            //self
            MsgQueueModule.getInstance().init(mContext);
            //pic
//			ImageFetcherModule.getInstance().init(mContext);
            FrescoImageFetcherModule.getInstance().init(mContext);
            //basic http operation,it can be used to commit data to server like Chrome FireFox IE
            HttpRequestModule.getInstance().init(mContext);
            //can fetch json and object,it is the business api util
            DataFetchModule.getInstance().init(mContext);
            //init BuilderTypeManager
            BuilderTypeManager.getInstance();
            //防盗链
            WatchDog.getInstance().runWatch(mContext);
            // database
            DBManage.create(mContext, AbsWasuDbListener.DATABASE_VERSION, AbsWasuDbListener.DATABASE_NAME, new Class<?>[]{DBProgramHistory.class, DBProgramFavorite.class, DBProgramChildFavorite.class}, new SaveFavoriteTimeListener());
            //auth
            AuthSDK.getInstance().init(mContext, new AuthConfig(BuildType.SITE_ID, BuildType.TVID, BuildType.ManageUrl, BuildType.PlayUrl, BuildType.PayUrl, null, BuildConfig.DEBUG));

            //statistics
//			if (apkDebugAble) {
//				//WLog.getInstance().init(WLog.TYPE_ANDROID, LogLevel.VERBOSE, null);
//				WasuStatistics.getInstance().init(this, Common.appKey,Common.appSecret, AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID),
//						AuthSDK.getInstance().getValue(IAuthInterface.KEY_USERKEY), WasuStatistics.NONE);
//			}else {
//				//WLog.getInstance().init(WLog.TYPE_ANDROID, LogLevel.ERROR, null);
//				WasuStatistics.getInstance().init(this,Common.appKey,Common.appSecret, AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID),
//						AuthSDK.getInstance().getValue(IAuthInterface.KEY_USERKEY), BuildType.STATISTICS_OPEN);
//			}

            WasuStatistics.getInstance().init(getApplication(), Common.appKey, Common.appSecret, AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID),
                    AuthSDK.getInstance().getValue(IAuthInterface.KEY_USERKEY), BuildType.STATISTICS_OPEN);

            // 升级模块
            UpdatePresent.getInstance().init(mContext, BuildType.UPDATE_INFO, BuildType.UPDATE_INFO);
            //角标模块
            CornerMarkModule.getInstance().init(mContext);
            //广告功能
            WasuAdManager.getsInstance();
            WasuAdEngine.getInstance().setUseImageLoad(false);
            //屏保模块
            ScreenSaverModule.getInstance().init(mContext);
            //网络监听
            initNet();

            //应用基础配置
            getConfigData();

            //设备性能
            checkDevicePerformance();

            //缓存模块
            WasuCacheModule.getInstance().init(mContext);

            //咪咕影院
            AuthMiguModule.getInstance().init(mContext);

//			//sohu初始化
//			ServiceGuardReciver.checkAndRestartLocaleServer(getApplicationContext());
            //fresco图片加载库
            //Fresco.initialize(mContext);
            //leakCanary
            //LeakCanary.install(this);

            loadPatch();
        }
//		else{
//			//退出APP
//			System.exit(0);
//			Log.e("tag","exit0");
//		}
    }

    private void loadPatch() {
        Log.i(TAG, "loadPatch:" + Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");
        TinkerInstaller.onReceiveUpgradePatch(getApplication().getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");
    }

    /**
     * 判断是否是WASU进行
     *
     * @return
     */
    private boolean isWasuProcess(Context context) {
        String processName = AppUtil.getProcessName(context, android.os.Process.myPid());

        // WASU_PROCESS_NAME_FACTORY 都认为是WASU
        if (processName != null && TextUtils.equals(processName, WASU_PROCESS_NAME_FACTORY)) {
            return true;
        }

        if (processName != null && TextUtils.equals(processName, WASU_PROCESS_NAME_MARKET)) {
            return true;
        }

        return false;
    }

    /**
     * 获取mContext
     *
     * @return
     */
    public static Context getContext() {
        return mContext;
    }

    private void initNet() {
        mAppReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                    AppUtil.updateNetConn(mContext);
                }
            }
        };

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        getApplication().registerReceiver(mAppReceiver, intentFilter);

        try {
            LocalBroadcastManager.getInstance(getContext()).registerReceiver(mAppReceiver, intentFilter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        WLog.d("AuthMiguModule", "onTerminate");
        //sohu
        ServiceGuardReciver.cancelUpdateBroadcast(mContext);
        ServiceGuardReciver.stopService(mContext);

        if (mAppReceiver != null) {
            try {
                getApplication().unregisterReceiver(mAppReceiver);
                LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mAppReceiver);
            } catch (Exception e) {
                e.printStackTrace();
            }
            mAppReceiver = null;
        }
        MAX_LAYER = 3;
        AuthMiguModule.getInstance().destory();
    }

    /**
     * 在application中获取APP配置信息
     * danxingxi
     */
    public void getConfigData() {
        DataFetchModule.getInstance().fetchJsonGet(Common.CONFIG_URL, new DataFetchListener.JsonListener() {

            @Override
            public void onJsonGet(int retcode, String extraMsg, JSONObject jsondata) {
                if (retcode != 0) {
                    WLog.e(TAG, "fetch config data failure");
                } else {
                    try {
                        Gson gson = new Gson();
                        configData = gson.fromJson(jsondata.toString(), ConfigData.class);
                        saveConfigData();
                    } catch (JsonSyntaxException e) {
                        e.printStackTrace();
                        WLog.e(TAG, "Json data error");
                    }
                }
            }
        });
    }

    /**
     * 把角标信息存储在SharedPreferences中
     * danxingxi
     */
    @SuppressLint("CommitPrefEdits")
    public void saveConfigData() {
        SharedPreferences sp = getApplication().getSharedPreferences("configData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        if (configData.getData().getCornerMarks().size() > 0) {
            for (ConfigData.DataEntity.CornerMarksEntity cornerMark : configData.getData().getCornerMarks()) {
                editor.putString(cornerMark.getCmark(), cornerMark.getPicUrl());
            }
        }
        editor.putString("playCover", configData.getData().getPlayCoverPicUrl());
        editor.commit();
    }

    /**
     * 检查设备的配置性能
     */
    private void checkDevicePerformance() {
        if (AppUtil.getTotalMemory(mContext) > 512) {
            isHighDevice = true;
        } else {
            isHighDevice = false;
        }

        SharedPreferences sp = getApplication().getSharedPreferences("deviceData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean("isHighDevice", isHighDevice);
        editor.commit();
    }

    /**
     * 获取IP地址
     * by danxingxi
     *
     * @return
     */
    public static String getIpAddress() {
        return AppUtil.getIpAddress(mContext);
    }


}
