package com.doverfuelingsolutions.issp.driver.usb;

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.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.widget.Toast;

import com.doverfuelingsolutions.issp.utils.log.DFSLog;

import java.util.HashSet;
import java.util.Set;

public class UsbTools {
    private static UsbTools INSTANCE;
    private final static String TAG = "UsbTools";
    private Context context;
    private UsbManager usgManager;
    private UsbReceiver usbReceiver;
    private Set<UsbDevice> usbDeviceSet = new HashSet<UsbDevice>();

    private UsbDevice openedDevice;
    private UsbInterface openedUsbInterface;
    private UsbDeviceConnection openedUsbConnection;
    private UsbEndpoint usbReadEndpoint;
    private UsbEndpoint usbWriteEndpoint;
    private Integer vendorId;
    private Set<Integer> productIds = new HashSet<Integer>();
    private static final String ACTION_USB_PERMISSION = "com.usb.sample.USB_PERMISSION";

    public static UsbTools getInstance(Context context) {
        if (INSTANCE == null) {
            INSTANCE = new UsbTools(context);
        }
        return INSTANCE;
    }

    private UsbTools(Context context) {
        this.context = context;
        this.usgManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        this.usbReceiver = new UsbReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        context.registerReceiver(this.usbReceiver, filter);
    }

    public void queryUsbDevice(int vendorId, int... productId) {
        this.vendorId = vendorId;
        for (int pid : productId) {
            this.productIds.add(pid);
        }
        for (UsbDevice device : usgManager.getDeviceList().values()) {
            if (device.getVendorId() == vendorId && this.productIds.contains(device.getProductId())) {
                if (usgManager.hasPermission(device)) {
                    usbDeviceSet.add(device);
                } else {
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
                    usgManager.requestPermission(device, pendingIntent);
                }
            }
        }
    }

    public Set<UsbDevice> getDeviceList() {
        return usbDeviceSet;
    }

    public boolean openUsbDevice(UsbDevice device) {
        if (openedDevice != null && openedDevice != device) {
            closeOpenDevice();
        }
        int interfaceCount = device.getInterfaceCount();
        DFSLog.Companion.i(TAG, " openUsbDevice getInterfaceCount():" + interfaceCount);
        if (interfaceCount == 0) {
            return false;
        } else {
            if (interfaceCount > 0) {
                openedUsbInterface = device.getInterface(0);
                if (openedUsbInterface == null) {
                    closeOpenDevice();
                    return false;
                }
                if (openedUsbInterface.getEndpointCount() > 0) {
                    usbWriteEndpoint = openedUsbInterface.getEndpoint(0);
                    if (openedUsbInterface.getEndpointCount() > 1) {
                        usbReadEndpoint = openedUsbInterface.getEndpoint(1);
                    }
                } else {
                    closeOpenDevice();
                    return false;
                }
                this.openedUsbConnection = this.usgManager.openDevice(device);
                if (this.openedUsbConnection == null) {
                    closeOpenDevice();
                    return false;
                } else if (this.openedUsbConnection.claimInterface(openedUsbInterface, true)) {
                    openedDevice = device;
                    return true;
                } else {
                    closeOpenDevice();
                    return false;
                }
            }
        }
        return false;
    }

    public boolean closeOpenDevice() {
        try {
            if (this.openedUsbConnection != null && this.openedUsbInterface != null) {
                this.openedUsbConnection.releaseInterface(this.openedUsbInterface);
            }
            if (openedUsbConnection != null) {
                this.openedUsbConnection.close();
            }
            this.openedUsbInterface = null;
            this.openedUsbConnection = null;
            openedDevice = null;
            usbWriteEndpoint = null;
            usbReadEndpoint = null;
        } catch (Exception var2) {
            DFSLog.Companion.e(var2);
        }
        return true;
    }

    public boolean isConnected() {
        return openedDevice != null && usbWriteEndpoint != null && usbReadEndpoint != null;
    }

    public int write(byte[] var1) {
        return this.write(var1, var1.length);
    }

    public int write(byte[] var1, int var2) {
        if (openedDevice == null || usbWriteEndpoint == null) {
            return -1;
        }
        int var6 = 0;
        int var4;
        for (byte[] var5 = new byte[4096]; var6 < var2; var6 += var4) {
            var4 = 4096;
            if (var6 + 4096 > var2) {
                var4 = var2 - var6;
            }
            System.arraycopy(var1, var6, var5, 0, var4);
            var4 = this.openedUsbConnection.bulkTransfer(usbWriteEndpoint, var5, var4, 3000);
            DFSLog.Companion.i(TAG, "write length:" + String.valueOf(var4));
            if (var4 < 0) {
                return -1;
            }
        }
        return var6;
    }

    public int read(byte[] var1) {
        if (openedDevice == null || usbWriteEndpoint == null) {
            return -1;
        }
        int var4 = this.openedUsbConnection.bulkTransfer(usbReadEndpoint, var1, var1.length, 100);
        DFSLog.Companion.i(TAG, "read length:" + var4);
        return var4;
    }

    private void onUsbReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (vendorId == null || (device.getVendorId() == vendorId && this.productIds.contains(device.getProductId()))) {
                if (usgManager.hasPermission(device)) {
                    usbDeviceSet.add(device);
                } else {
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
                    usgManager.requestPermission(device, pendingIntent);
                }
            }
        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            usbDeviceSet.remove(device);
            if (openedDevice == device) {
                closeOpenDevice();
            }
        } else if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (vendorId == null || (device.getVendorId() == vendorId && this.productIds.contains(device.getProductId()))) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        usbDeviceSet.add(device);
                    } else {
                        Toast.makeText(context, "permission denied for device", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

    private class UsbReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            INSTANCE.onUsbReceive(context, intent);
        }
    }
}
