package tech.starwin.utils.context_utils;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;

import com.common.bean.AppInfoBean;
import com.common.bean.DeviceInfoBean;
import com.common.bean.DisplayBean;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import tech.starwin.BuildConfig;
import tech.starwin.LibConfig;
import tech.starwin.utils.LogUtils;
import tech.starwin.utils.PreferencesManager;
import tech.starwin.utils.format_utils.StringFormat;

/**
 * Created by SiKang on 2019-11-15.
 */
public class DeviceUtils {
    private DeviceInfoBean deviceInfoBean;
    private static DeviceUtils deviceUtils = new DeviceUtils();
    private String activePkgList;


    private String[] pkgBlackList = new String[]{
//            "androidx.test.tools.crawler",
//            "androidx.test.services",
//            "android.support.test.services",
//            "com.google.android.gmscore.testing.testsupport",
//            "com.google.android.gms.policy_test_support",
//            "com.google.android.apps.mtaas.testloop",
//            "com.google.android.apps.mtaas.loginutil",
//            "com.google.android.apps.mtaas.deviceadmin",
//            "com.google.android.apps.mtaas.updateutil",
//            "com.google.android.apps.auth.test.support",
//            "com.google.android.instantapps.devman",
//            "com.google.android.instantapps.supervisor"
            "YW5kcm9pZHgudGVzdC50b29scy5jcmF3bGVy",
            "YW5kcm9pZHgudGVzdC5zZXJ2aWNlcw==",
            "YW5kcm9pZC5zdXBwb3J0LnRlc3Quc2VydmljZXM=",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmdtc2NvcmUudGVzdGluZy50ZXN0c3VwcG9ydA==",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmdtcy5wb2xpY3lfdGVzdF9zdXBwb3J0",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMubXRhYXMudGVzdGxvb3A=",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMubXRhYXMubG9naW51dGls",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMubXRhYXMuZGV2aWNlYWRtaW4=",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMubXRhYXMudXBkYXRldXRpbA==",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuYXV0aC50ZXN0LnN1cHBvcnQ=",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmluc3RhbnRhcHBzLmRldm1hbg=="

    };

    private String[] pkgWhiteList = new String[]{
            StringFormat.base64(BuildConfig.PACKAGE_NAME),
//            "com.google.android.music",
//            "com.google.android.apps.photos",
//            "com.google.android.apps.tachyon",
//            "com.google.android.videos",
//            "com.google.android.keep",
//            "com.google.android.apps.plus",
//            "com.google.android.apps.books",
//            "%com.facebook%",
//            "%com.instagram%",
//            "%com.google.android.apps.docs%",
//            "%com.google.ar%",
//            "%com.google.vr%",
//            "%com.samsung%",
//            "%com.sec.android%"
            "Y29tLmdvb2dsZS5hbmRyb2lkLm11c2lj",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMucGhvdG9z",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMudGFjaHlvbg==",
            "Y29tLmdvb2dsZS5hbmRyb2lkLnZpZGVvcw==",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmtlZXA=",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMucGx1cw==",
            "Y29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuYm9va3M=",
            "JWNvbS5mYWNlYm9vayU=",
            "JWNvbS5pbnN0YWdyYW0l",
            "JWNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLmRvY3Ml",
            "JWNvbS5nb29nbGUuYXIl",
            "JWNvbS5nb29nbGUudnIl",
            "JWNvbS5zYW1zdW5nJQ==",
            "JWNvbS5zZWMuYW5kcm9pZCU="
    };


    public static DeviceUtils getInstance() {
        return deviceUtils;
    }

    DeviceUtils() {
        deviceInfoBean = new DeviceInfoBean();
    }

    /**
     * 如果APP更改了语言，需要在更改之前初始化
     */
    public void init(Context context) {
        try {
            deviceInfoBean.setScreenWidth(context.getResources().getDisplayMetrics().widthPixels);
            deviceInfoBean.setScreenHeight(context.getResources().getDisplayMetrics().heightPixels);
            deviceInfoBean.setRoot(AppInfoUtils.isRoot());
            deviceInfoBean.setAndroidId(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));

            deviceInfoBean.setLocal(Locale.getDefault());
            deviceInfoBean.setTimeZone(TimeZone.getDefault());

            long[] ramInfo = getRAMInfo(context);
            deviceInfoBean.setTotalMemory(ramInfo[0]);
            deviceInfoBean.setFreeMemory(ramInfo[1]);

            long[] romInfo = getROMInfo();
            deviceInfoBean.setDiskSpace(romInfo[0]);
            deviceInfoBean.setDiskFreeSpace(romInfo[1]);

            deviceInfoBean.setAppSign(BuildConfig.KEYSTORE_SIGN);
            deviceInfoBean.setBaseBandVersion(getBaseBandVersion());
            deviceInfoBean.setBattery(getBattery(context));
            deviceInfoBean.setBluetooth(Settings.Secure.getString(context.getContentResolver(), "bluetooth_address"));
            deviceInfoBean.setDebug((Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED, 0) > 0));
            deviceInfoBean.setSimulator(isSimulator());
            deviceInfoBean.setKernelVersion(getKernelVersion());
            deviceInfoBean.setMacAddress(getMacAddress());
            deviceInfoBean.setUpTime(SystemClock.elapsedRealtime());
            deviceInfoBean.setCameraNum(Camera.getNumberOfCameras());
        } catch (Exception e) {

        }


//        WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//        deviceInfoBean.setWifiSsid(wifi.getConnectionInfo().getSSID());
//        deviceInfoBean.setWifiBssid(wifi.getConnectionInfo().getBSSID());
//        deviceInfoBean.setWifiRssi(wifi.getConnectionInfo().getRssi());
    }


    /**
     * 设备信息
     */
    public DeviceInfoBean getDeviceInfo() {
        return deviceInfoBean;
    }


    /**
     * 已安装应用列表
     */
    public List<AppInfoBean> getAppList(Context context) {
        List<AppInfoBean> appList = new ArrayList<>();
        try {
            PackageManager manager = context.getPackageManager();
            List<PackageInfo> packages = manager.getInstalledPackages(0);
            for (int i = 0; i < packages.size(); i++) {
                PackageInfo packageInfo = packages.get(i);
                AppInfoBean appInfoBean = new AppInfoBean();
                appInfoBean.setVersionName(packageInfo.versionName);
                appInfoBean.setVersionCode(packageInfo.versionCode);
                appInfoBean.setPackageName(packageInfo.packageName);
                appInfoBean.setAppName(manager.getApplicationInfo(packageInfo.packageName, 0).loadLabel(manager).toString());
                appInfoBean.setFirstInstallTime(packageInfo.firstInstallTime);
                appInfoBean.setSystemApp((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    appInfoBean.setGameApp(packageInfo.applicationInfo.flags == ApplicationInfo.CATEGORY_GAME);
                }
                appInfoBean.setRequestedPermissions(packageInfo.requestedPermissions);

                appList.add(appInfoBean);
            }
        } catch (Exception e) {
        }
        return appList;
    }


    /**
     * 最常用的包名
     *
     * @param count 指定数量
     */
    public String getActivePkgs(Context context, int count) {
        StringBuilder builder = new StringBuilder();
        try {
            List<PackageInfo> appList = new ArrayList<>();
            PackageManager manager = context.getPackageManager();
            List<PackageInfo> packages = manager.getInstalledPackages(0);

            for (int i = 0; i < packages.size(); i++) {
                PackageInfo packageInfo = packages.get(i);
                if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    boolean isWhiteList = false;
                    for (String pkgName : pkgWhiteList) {
                        pkgName = StringFormat.fromBase64(pkgName);
                        if (pkgName.contains("%")) {
                            if (packageInfo.packageName.contains(pkgName.replace("%", ""))) {
                                isWhiteList = true;
                            }
                        } else if (packageInfo.packageName.equals(pkgName)) {
                            isWhiteList = true;
                        }
                    }
                    if (!isWhiteList) {
                        appList.add(packageInfo);
                    }
                }
            }

            Collections.sort(appList, (lhs, rhs) -> {
                if (lhs == null || rhs == null) {
                    return 0;
                }
                if (lhs.lastUpdateTime < rhs.lastUpdateTime) {
                    return 1;
                } else if (lhs.lastUpdateTime > rhs.lastUpdateTime) {
                    return -1;
                } else {
                    return 0;
                }
            });

            appList = appList.subList(0, count);
            for (PackageInfo info : appList) {
                builder.append(info.packageName);
                builder.append("&");
            }
            return builder.toString();
        } catch (Exception e) {
        }
        return "";
    }

    /**
     * 是否是Google审核机器
     */
    public boolean isReviewMachine(Context context) {
        //如果是渠道包，忽略
        if (LibConfig.IS_COLLECT_MODE || PreferencesManager.get().isSafeUser()) {
            return false;
        }

        if (TextUtils.isEmpty(activePkgList)) {
            activePkgList = getActivePkgs(context, 100);
        }

        //如果发现包名黑名单，true
        for (String pkgName : pkgBlackList) {
            LogUtils.d("DeviceUtilsInfo", StringFormat.fromBase64(pkgName));
            if (activePkgList.contains(StringFormat.fromBase64(pkgName))) {
                return true;
            }
        }

        //时区不是印尼，true
        if (!isIDTime(TimeZone.getDefault())) {
            return true;
        }

        DisplayBean displayBean = PreferencesManager.get().getCustomerInfo();
        return (displayBean != null && displayBean.isFakeProductFlag());
    }

    /**
     * 进入假界面原因
     */
    public String fakeReason(Context context) {
        //如果是渠道包，忽略
        if (LibConfig.IS_COLLECT_MODE || PreferencesManager.get().isSafeUser()) {
            return "";
        }

        if (TextUtils.isEmpty(activePkgList)) {
            activePkgList = getActivePkgs(context, 100);
        }

        //如果发现包名黑名单，true
        for (String pkgName : pkgBlackList) {
            LogUtils.d("DeviceUtilsInfo", StringFormat.fromBase64(pkgName));
            if (activePkgList.contains(StringFormat.fromBase64(pkgName))) {
                return pkgName;
            }
        }

        //时区不是印尼，true
        if (!isIDTime(TimeZone.getDefault())) {
            return "timeZone";
        }

        DisplayBean displayBean = PreferencesManager.get().getCustomerInfo();
        if((displayBean != null && displayBean.isFakeProductFlag())){
            return "display";
        }else{
            return "";
        }
    }


    /**
     * 根据硬件信息计算设备指纹
     */
    public static String getSignFromHardware() {
        return Build.BOARD + Build.BRAND +
                Build.CPU_ABI + Build.DEVICE +
                Build.DISPLAY + Build.HOST +
                Build.ID + Build.MANUFACTURER +
                Build.MODEL + Build.PRODUCT +
                Build.TAGS + Build.TYPE +
                Build.USER;

    }


    /**
     * 是否是印尼时区
     */
    private static boolean isIDTime(TimeZone timeZone) {
        String displayName = timeZone.getDisplayName(false, TimeZone.SHORT);
        //时区代码
        String idTime = "WIB/WITA/WIT/";
        if (idTime.contains(displayName + "/") || "Asia/Shanghai".equals(timeZone.getID())) {
            return true;
        }

        //城市信息
        String idCity = "Asia/Jayapura,Asia/Makassar,Asia/Jakarta,Asia/Pontianak";
        return idCity.contains(timeZone.getID());

    }


    private long[] getRAMInfo(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
        manager.getMemoryInfo(info);
        return new long[]{info.totalMem, info.availMem};
    }

    private long[] getROMInfo() {
        final StatFs statFs = new StatFs(Environment.getDataDirectory().getPath());
        long totalCounts = statFs.getBlockCountLong();//总共的block数
        long availableCounts = statFs.getAvailableBlocksLong(); //获取可用的block数
        long size = statFs.getBlockSizeLong(); //每格所占的大小，一般是4KB==
        long availROMSize = availableCounts * size;//可用内部存储大小
        long totalROMSize = totalCounts * size; //内部存储总大小
        return new long[]{totalROMSize, availROMSize};

    }

    public String getBaseBandVersion() {
        String version = "";
        try {
            @SuppressLint("PrivateApi") Class cl = Class.forName("android.os.SystemProperties");
            Object invoker = cl.newInstance();
            //noinspection unchecked
            Method m = cl.getMethod("get", String.class, String.class);
            Object result = m.invoke(invoker, "gsm.version.baseband", "no message");
            version = (String) result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        String radioVersion = Build.getRadioVersion();
        version = TextUtils.isEmpty(version) ? radioVersion : version;
        return version == null ? "" : version;
    }

    /**
     * 电池信息
     *
     * @param context
     * @return
     */
    public int getBattery(Context context) {
        //API >= 21 (5.0，L)
        BatteryManager manager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);

        int batteryCurrentCap = 0;///当前电量百分比
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            batteryCurrentCap = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        } else {
            Intent intent = new ContextWrapper(context).registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            if (intent != null) {
                batteryCurrentCap = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            }
        }
        return batteryCurrentCap;
    }


    /*
     *根据CPU是否为电脑来判断是否为模拟器
     *返回:true 为模拟器
     */
    public boolean isSimulator() {
        try {
            String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
            ProcessBuilder cmd = new ProcessBuilder(args);

            Process process = cmd.start();
            StringBuffer sb = new StringBuffer();
            String readLine = "";
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));
            while ((readLine = responseReader.readLine()) != null) {
                sb.append(readLine);
            }
            responseReader.close();
            String cpuInfo = sb.toString().toLowerCase();
            if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    public String getKernelVersion() {
        Process process;
        String mLinuxKernal = null;
        try {
            process = Runtime.getRuntime().exec("cat /proc/version");
            if (process != null) {
                InputStream outs = process.getInputStream();
                InputStreamReader isrout = new InputStreamReader(outs);
                BufferedReader brout = new BufferedReader(isrout, 8 * 1024);

                StringBuilder result = new StringBuilder();
                String line;
                // get the whole standard output string
                try {
                    while ((line = brout.readLine()) != null) {
                        result.append(line);
                        // result += "\n";
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (!"".equals(result.toString())) {
                    String keyword = "version ";
                    int index = result.indexOf(keyword);
                    line = result.substring(index + keyword.length());
                    index = line.indexOf(" ");
                    mLinuxKernal = line.substring(0, index);
                }
            }
            mLinuxKernal = TextUtils.isEmpty(mLinuxKernal) ? System.getProperty("os.version") : mLinuxKernal;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return mLinuxKernal == null ? "" : mLinuxKernal;
    }


    /**
     * 获取mac地址
     *
     * @return
     */
    public String getMacAddress() {
        String macAddress = null;
        StringBuffer buf = new StringBuffer();
        NetworkInterface networkInterface = null;
        try {
            networkInterface = NetworkInterface.getByName("eth1");
            if (networkInterface == null) {
                networkInterface = NetworkInterface.getByName("wlan0");
            }
            if (networkInterface == null) {
                return "";
            }
            byte[] addr = networkInterface.getHardwareAddress();
            for (byte b : addr) {
                buf.append(String.format("%02X:", b));
            }
            if (buf.length() > 0) {
                buf.deleteCharAt(buf.length() - 1);
            }
            macAddress = buf.toString();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return macAddress == null ? "" : macAddress;
    }


}
