#!/usr/bin/python
import os
import subprocess
from re import match

class WheelService:

    driver_path = '/sys/bus/hid/drivers/logitech'
    min_degrees=40
    max_degrees=900
    model_wheels_supported = ['DFP','DFGT', 'G25', 'G27', 'G29']

    def current_degrees(self):
        degrees=None
        try:
            degrees = int(self.read_from_driver('range'))
        except ValueError as verror:
            return None
        except TypeError as terror:
            return None
        return degrees

    def get_combine_pedals(self):
        try:
            combine_pedals=int(self.read_from_driver('combine_pedals'))
            if combine_pedals != 0:
                return True
            else:
                return False
        except ValueError as verror:
            return None
        except TypeError as terror:
            return None

    def get_alternate_modes(self):
        list_modes = None
        parameter = "alternate_modes"
        try:
            id_wheel_root = next(os.walk(self.driver_path))
            for device_dir in id_wheel_root[1]:
                if match(r'\d{4}:.{4}:.{4}\..{4}$', device_dir):
                    device_files = next(os.walk(self.driver_path + '/' + device_dir))
                    if parameter in device_files[2]:
                        with open(os.path.join(self.driver_path, device_dir, parameter), 'r') as alternate_modes_file:
                            list_modes = [line.rstrip('\n') for line in alternate_modes_file]
        except Exception:
            return None
        return list_modes

    def name_wheel(self):
        return self.read_from_driver('real_id')

    def supported_wheel(self):
        real_id = self.read_from_driver('real_id')
        if real_id is not None:
            for model in self.model_wheels_supported:
                if model in real_id:
                    supported_wheel = True
        else:
            supported_wheel = False
        return supported_wheel

    def read_from_driver(self,parameter):
        property_value = None
        try:
            id_wheel_root = next(os.walk(self.driver_path))
            for device_dir in id_wheel_root[1]:
                if match(r'\d{4}:.{4}:.{4}\..{4}$', device_dir):
                    device_files = next(os.walk(self.driver_path + '/' + device_dir))
                    if parameter in device_files[2]:
                        with open(os.path.join(self.driver_path, device_dir,parameter), 'r') as property:
                            property_value = str(property.readline())
        except Exception:
            property_value = None
        return property_value


class App:

    def __init__(self):
        self.wheel_service = WheelService()
        
    def execute(self):
        print("********** WHEEL DISCOVERY **********")
        print("USB INFORMATION:")
        output = None
        try:
            ps = subprocess.Popen(('lsusb'), stdout=subprocess.PIPE)
            output = subprocess.check_output(('grep', 'Logitech'), stdin=ps.stdout)
            ps.wait()
        except subprocess.CalledProcessError as error:
            output = "Not found Logitech devices"
        print("lsusb %s" % output)
        print("SYSFS INFORMATION:")
        driver_base_path = None
        degrees = self.wheel_service.current_degrees()
        if degrees is None:
            self.wheel_service.driver_path = "/sys/bus/hid/drivers/logitech-hidpp-device/"
        degrees = self.wheel_service.current_degrees()
        if degrees is not None:
            driver_base_path = self.wheel_service.driver_path
        print("driver base path: %s " % driver_base_path)
        print("range: %s" % degrees)
        print("combine_pedals: %s" % self.wheel_service.get_combine_pedals())
        print("alternate modes: %s" % self.wheel_service.get_alternate_modes())
        print("real_id: %s" % self.wheel_service.name_wheel())


if __name__ == '__main__':
    app = App()
    app.execute()
