package xn.hxp.utils;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class USBHelper {

    private static final String TAG = USBHelper.class.getSimpleName();
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
    private static final String ACTION_USB_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";

    private static Set<Integer> sFilter = new HashSet<>();
    private static volatile USBHelper ins;

    static {
        sFilter.add(0x4b43);
        sFilter.add(0x0fe6);
    }

    private Context mContext;
    private UsbManager mUsbManager;
    private UsbDevice mDevice = null;

    private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            UsbDevice device = (UsbDevice)intent.getParcelableExtra("device");
            onUsbReceive(action,device,intent.getBooleanExtra("permission", false));
        }
    };

    private USBHelper(){

    }

    public static USBHelper getIns(){
        if(ins == null){
            synchronized(USBHelper.class){
                if(ins == null){
                    ins = new USBHelper();
                }
            }
        }
        return ins;
    }

    private synchronized void onUsbReceive(String action,UsbDevice device,boolean hasPermission){
        if(device == null)return;
        if (TextUtils.equals(ACTION_USB_PERMISSION,action)) {
            if (hasPermission) {
                mDevice = device;
                Log.i("UsbApi", "设备获取权限成功：VID是" + device.getVendorId() + "  PID是" + device.getProductId()+" deviceName："+device.getDeviceName());
            } else {
                mDevice = null;
                Log.e("UsbApi", "设备获取权限失败：VID是" + device.getVendorId() + "  PID是" + device.getProductId()+" deviceName："+device.getDeviceName());
            }
        } else {
            if (TextUtils.equals(ACTION_USB_ATTACHED,action)) {
                onDetached(device);
            } else if (TextUtils.equals(ACTION_USB_DETACHED,action)) {
                onDetached(device);
            }
        }
    }

    private void onDetached(UsbDevice device){
        if(device == null || mDevice == null)return;
        if(device.getDeviceId() == mDevice.getDeviceId()){
            mDevice = null;
        }
    }

    private void onAttached(UsbDevice device){
    }

    private void registerUsbReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_USB_ATTACHED);
        filter.addAction(ACTION_USB_PERMISSION);
        filter.addAction(ACTION_USB_DETACHED);
        mContext.registerReceiver(mUsbReceiver, filter);
    }

    public void onDestroy() {
        if(mUsbReceiver != null){
            mContext.unregisterReceiver(mUsbReceiver);
            mUsbReceiver = null;
        }
    }

    public void init(Context context){
        mContext = context;
        mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
        registerUsbReceiver();
    }

    public List<String> enumUsb(){
        List<String>retVal = new ArrayList<>();
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        if (deviceList.size() > 0) {
            UsbDevice device = null;
            while (deviceIterator.hasNext()) {
                device = deviceIterator.next();
                if (device != null && sFilter.contains(device.getVendorId())) {
                    retVal.add(String.format("VID:0x%04X,PID:0x%04X", device.getVendorId(), device.getProductId()));
                }
            }
        }
        return retVal;
    }

    private UsbDevice find(String devicePath){
        if(TextUtils.isEmpty(devicePath))return null;
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        if (deviceList.size() > 0) {
            UsbDevice device = null;
            while (deviceIterator.hasNext()) {
                device = deviceIterator.next();
                if (device != null && sFilter.contains(device.getVendorId())) {
                    if(TextUtils.equals(String.format("VID:0x%04X,PID:0x%04X", device.getVendorId(), device.getProductId()),devicePath)){
                        return device;
                    }
                }
            }
        }
        return null;
    }

    public boolean hasPermission(String devicePath){
        return hasPermission(find(devicePath));
    }

    public String getDevice() {
        if(mDevice != null){
            if(hasPermission(mDevice)){
                return String.format("VID:0x%04X,PID:0x%04X", mDevice.getVendorId(), mDevice.getProductId());
            }
            return null;
        }
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        if (deviceList.size() > 0) {
            UsbDevice device = null;
            while (deviceIterator.hasNext()) {
                device = deviceIterator.next();
                if (device != null && sFilter.contains(device.getVendorId())) {
                    if (!hasPermission(device)) {
                        return null;
                    } else {
                        return String.format("VID:0x%04X,PID:0x%04X", device.getVendorId(), device.getProductId());
                    }
                }
            }
        }
        return null;
    }

    private boolean hasPermission(UsbDevice device){
        if(device == null)return false;
        if (!mUsbManager.hasPermission(device)) {
            PendingIntent permissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(mContext.getPackageName()), 0);
            mUsbManager.requestPermission(device, permissionIntent);
            Toast.makeText(mContext, "没有权限请重新尝试连接 / Do not have permission，Please try again", Toast.LENGTH_LONG).show();
            return false;
        }
        return true;
    }

}
