from glob import glob
from subprocess import check_output, CalledProcessError
import platform
import os
from usbmonitor import USBMonitor
from usbmonitor.attributes import ID_MODEL, ID_MODEL_ID, ID_VENDOR_ID, DEVNAME


class USBDeviceHandler:
    def __init__(self):
        self.monitor = USBMonitor()
        self.startUSBmonitor()

    def startUSBmonitor(self):
        print(self.get_usb_devices())
        self.monitor.start_monitoring(self.on_connect, self.on_disconnect)

    def stopUSBmonitor(self):
        self.monitor.stop_monitoring()

    def device_info_str(self, device_info):
        return f"{device_info[ID_MODEL]} ({device_info[ID_MODEL_ID]} - {device_info[ID_VENDOR_ID]}) at {device_info[DEVNAME]}"

    def on_connect(self, device_id, device_info):
        print("Connected: " + self.device_info_str(device_info=device_info))
        print(self.get_usb_devices())

    def on_disconnect(self, device_id, device_info):
        print("Disconnected: " + self.device_info_str(device_info=device_info))
        print(self.get_usb_devices())

    def get_usb_devices(self):
        current_os = platform.system()
        print(current_os)

        # MacOS
        if current_os == "Darwin":
            os.chdir("/Volumes")
            # then do some listing
            List = os.listdir()
            i = 0
            while i < len(List):
                if List[i] == "Macintosh HD" or List[i] == "Recovery":
                    del List[i : i + 1]
                    continue
                else:
                    List[i] = "/Volumes/" + List[i]
                    i += 1

            return List

        # Linux
        elif current_os == "Linux":

            def get_linux_usb_devices():
                sdb_devices = map(os.path.realpath, glob("/sys/block/sd*"))
                usb_devices = (dev for dev in sdb_devices if "usb" in dev.split("/")[5])
                return dict((os.path.basename(dev), dev) for dev in usb_devices)

            devices = get_linux_usb_devices()
            output = check_output(["mount"]).splitlines()
            is_usb = lambda path: any(dev in path for dev in devices)
            usb_info = (line for line in output if is_usb(line.split()[0]))
            return [(info.split()[0], info.split()[2]) for info in usb_info]
