package com.sheep.gamegroup.util;

import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.sheep.gamegroup.model.api.BaseMessageConverter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * Created by realicing on 2018/5/24.
 * realicing@sina.com
 */
public class DeviceIDUtil {
    private static DeviceIDUtil deviceIDUtil;

    /*
     *
     *  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     *  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     *  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     *
     * */
    private static final String SHARED_PREFERENCES_NAME = "deviceid_cache";
    //.开头隐藏文件和隐藏文件夹
    private static final String FILE_PATH = "data/.cache/.1270f37f6c8";

    private static final String LOACL_UUID = "my_device_localuuid";
    private static final String LOACL_MAC = "my_device_local_mac";
    private static final String LOACL_IMEI = "my_device_local_imei";
    private static final String LOACL_DEVICE_IMEI = "my_device_local_device_imei";


    private static final String LOACL_DEVICE_ID = "my_device_loacl_device_id";

    private static final String LOACL_FILENAME_KEY = "loacl_filename_key";


    public static DeviceIDUtil newInstance(){
        if (deviceIDUtil == null)
            deviceIDUtil = new DeviceIDUtil();
        return deviceIDUtil;
    }


    //获取设备唯一id
    public static String getDeviceId(Context mContext) {
      /*  Log.d("DeviceIDUtils", "getLocalDeviceId:" + getLocalDeviceId());
        Log.d("DeviceIDUtils", "getMacid:" + getMacid());
        Log.d("DeviceIDUtils", "getMac60:" + getMac60());
        Log.d("DeviceIDUtils", "getMac60_1:" + getMac60_1());
        Log.d("DeviceIDUtils", "getMac60_2:" + getMac60_2());
        Log.d("DeviceIDUtils", "getimei:" + getimei());
        Log.d("DeviceIDUtils", "getDiviceInfoIMEI:" + getDiviceInfoIMEI());
        Log.d("DeviceIDUtils", "getLocalUUID:" + getLocalUUID());
        Log.d("DeviceIDUtils", "getFileName:" + getFileName());
*/
        String localDeviceId = getLocalDeviceId(mContext);
        if (!TextUtils.isEmpty(localDeviceId)) {
            return localDeviceId;
        }
        //先获取获取默认的imei
        String diviceid = getimei(mContext);

        //如果为空获取MAC地址
        if (TextUtils.isEmpty(diviceid)) {
            diviceid = getMacid(mContext);
        }

        //如果还为空择取设备信息拼接出来的id
        if (TextUtils.isEmpty(diviceid)) {
            diviceid = getDiviceInfoIMEI(mContext);
        }

        //如果还为空则生成并保存一个唯一的UUID
        if (TextUtils.isEmpty(diviceid)) {
            diviceid = getLocalUUID(mContext);
        }

        Log.d("DeviceIDUtils", "return diviceid:" + diviceid);
        saveDeviceId(mContext, diviceid);
        return diviceid;
    }

    private static String getLocalDeviceId(Context mContext) {
        String savaString = getSavaString(mContext, LOACL_DEVICE_ID, "");
        if (TextUtils.isEmpty(savaString)) {
            String s = readSDFile();
            if (!TextUtils.isEmpty(s)) {
                savaString(mContext, LOACL_DEVICE_ID, s);
                return s;
            }
        } else {
            return savaString;
        }

        return null;
    }

    private static void saveDeviceId(Context mContext, String diviceid) {
        savaString(mContext, LOACL_DEVICE_ID, diviceid);
        //加密保存
        saveFile(BaseMessageConverter.encrypt(diviceid));
    }

    private static void saveFile(String str) {
        String filePath;
        boolean hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (hasSDCard) { // SD卡根目录的hello.text
            filePath = Environment.getExternalStorageDirectory().toString() + File.separator + FILE_PATH + File.separator + getFileName();
        } else {  // 系统下载缓存根目录的hello.text
            filePath = Environment.getDownloadCacheDirectory().toString() + File.separator + FILE_PATH + File.separator + getFileName();
        }
        try {
            File file = new File(filePath);
            //不存在則重新保存
            if (!file.exists()) {
                Log.d("DeviceIDUtils", "saveFile filePath:" + filePath);
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
                FileOutputStream outStream = new FileOutputStream(file);
                outStream.write(str.getBytes());
                outStream.close();
            } else {
                Log.d("DeviceIDUtils", "saveFile 文件已存在:" + filePath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String getFileName() {
        //两种模式，随机的文件名和固定文件名，可以根据需求自行更换
        //随机的文件名
       /* String savaFileName = getSavaString(LOACL_FILENAME_KEY, "");
        if (TextUtils.isEmpty(savaFileName)) {
            String uuid = UUID.randomUUID().toString().replace("-", "");
            savaString(LOACL_FILENAME_KEY, uuid);
            Log.d("DeviceIDUtils", "getFileName:" + uuid);
            return uuid;
        } else {
            Log.d("DeviceIDUtils", "getFileName:" + savaFileName);
            return savaFileName;
        }*/


        //固定文件名
        return ".abcdefg60232414f87c77dcc737f2f0c";
    }

    private static String readSDFile() {
        try {
            String filePath;
            boolean hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
            if (hasSDCard) { // SD卡根目录的hello.text
                filePath = Environment.getExternalStorageDirectory().toString() + File.separator + FILE_PATH + File.separator + getFileName();
            } else {  // 系统下载缓存根目录的hello.text
                filePath = Environment.getDownloadCacheDirectory().toString() + File.separator + FILE_PATH + File.separator + getFileName();
            }
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            int length = fis.available();

            byte[] buffer = new byte[length];
            fis.read(buffer);
            String res = new String(buffer, "utf-8");
            fis.close();
            Log.d("DeviceIDUtils", "readSDFile filePath:" + filePath);
            Log.d("DeviceIDUtils", "readSDFile res:" + res);
            //解密
            return BaseMessageConverter.decrypt(res);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    private static String getLocalUUID(Context mContext) {
        String localuuid = getSavaString(mContext, LOACL_UUID, "");
        if (TextUtils.isEmpty(localuuid)) {
            localuuid = UUID.randomUUID().toString().replace("-", "");
            savaString(mContext, LOACL_UUID, localuuid);
        }
        return localuuid;
    }

    private static String getMacid(Context mContext) {
        String WLANMAC = getSavaString(mContext, LOACL_MAC, "");
        if (!TextUtils.isEmpty(WLANMAC)) {
            return WLANMAC;
        }

        if (Build.VERSION.SDK_INT >= 23) {
            WLANMAC = getMac60();
        } else {
            WifiManager wm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
            WLANMAC = wm.getConnectionInfo().getMacAddress();
            if (TextUtils.isEmpty(WLANMAC) || "02:00:00:00:00:00".equals(WLANMAC)) {
                WLANMAC = getMac60();
            }
        }

        //在Android6.0的版本以后用原来的getMacAddress()方法获取手机的MAC地址都为：02:00:00:00:00:00这个固定的值
        if ("02:00:00:00:00:00".equals(WLANMAC)) {
            WLANMAC = null;
        }

        if (!TextUtils.isEmpty(WLANMAC)) {
            WLANMAC = WLANMAC.replaceAll(":", "");
            savaString(mContext, LOACL_MAC, WLANMAC);
        }
        return WLANMAC;
    }


    private static String getMac60() {
        String mac = getMac60_1();
        if (TextUtils.isEmpty(mac) || "02:00:00:00:00:00".equals(mac)) {
            mac = getMac60_2();
        }
        return mac;
    }

    private static String getMac60_1() {
        String str = "";
        String macSerial = "";
        try {
            Process pp = Runtime.getRuntime().exec(
                    "cat /sys/class/net/wlan0/address ");
            InputStreamReader ir = new InputStreamReader(pp.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);

            for (; null != str; ) {
                str = input.readLine();
                if (str != null) {
                    macSerial = str.trim();// 去空格
                    break;
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (TextUtils.isEmpty(macSerial)) {
            try {
                return loadFileAsString("/sys/class/net/eth0/address")
                        .toUpperCase().substring(0, 17);
            } catch (Exception e) {
                e.printStackTrace();

            }

        }

        //转换成小写
        if (!TextUtils.isEmpty(macSerial)) {
            macSerial = macSerial.toLowerCase();
        }
        return macSerial;
    }

    private static String getMac60_2() {
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (!nif.getName().equalsIgnoreCase("wlan0")) continue;

                byte[] macBytes = nif.getHardwareAddress();
                if (macBytes == null) {
                    return "";
                }

                StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
                    res1.append(String.format("%02X:", b));
                }

                if (res1.length() > 0) {
                    res1.deleteCharAt(res1.length() - 1);
                }
                String mac = res1.toString();
                //转换成小写
                if (!TextUtils.isEmpty(mac)) {
                    mac = mac.toLowerCase();
                }
                return mac;
            }
        } catch (Exception ignored) {
        }
        return null;
    }

    private static String loadFileAsString(String fileName) throws Exception {
        FileReader reader = new FileReader(fileName);
        String text = loadReaderAsString(reader);
        reader.close();
        return text;
    }

    private static String loadReaderAsString(Reader reader) throws Exception {
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[4096];
        int readLength = reader.read(buffer);
        while (readLength >= 0) {
            builder.append(buffer, 0, readLength);
            readLength = reader.read(buffer);
        }
        return builder.toString();
    }


    //通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现
    private static String getDiviceInfoIMEI(Context mContext) {
        String device_imei = getSavaString(mContext, LOACL_DEVICE_IMEI, "");
        if (!TextUtils.isEmpty(device_imei)) {
            return device_imei;
        }

        device_imei = "35" + //we make this look like a valid IMEI
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10; //13 digits

        if (!TextUtils.isEmpty(device_imei)) {
            savaString(mContext, LOACL_DEVICE_IMEI, device_imei);
        }
        return device_imei;
    }

    public static String getimei(Context mContext) {
        String imei = getSavaString(mContext, LOACL_IMEI, "");
        if (!TextUtils.isEmpty(imei)) {
            return imei;
        }

        try {
            TelephonyManager tm = (TelephonyManager) mContext
                    .getSystemService(Context.TELEPHONY_SERVICE);
            if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return null;
            }
            if(tm == null)
                return null;
            imei = tm.getDeviceId();
            if (!TextUtils.isEmpty(imei)) {
                savaString(mContext, LOACL_IMEI, imei);
            }
            return imei;
        } catch (Exception ignored) {

        }
        return null;
    }

    private static String getSavaString(Context mContext, String key, String defValue) {
        SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        return sp.getString(key, defValue);
    }

    private static void savaString(Context mContext, String key, String value) {
        SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        sp.edit().putString(key, value).apply();//提交保存键值对

    }

    /**
     * 数字转换成万 千 百 十
     */
    public String numberCnvert(int number){
        int wanWei = number / 10000;
        int qianWei = number % 10000 /1000;
        int baiWei = number % 1000 /100;
        int shiWei = number % 100 /10;
        int geWei = number % 10 ;

        StringBuffer stringBuffer = new StringBuffer();
        if(wanWei > 0){
            stringBuffer.append(wanWei+"万+");
        }else {
            stringBuffer.append(number % 10000 +"");
        }

        return stringBuffer.toString();
    }

}
