import os

from base_gpio_interface import BaseGPIOInterface
from gpio_map import GPIOMap

from periphery import GPIO # pylint: disable=import-error


class PeripheryGPIOInterface(BaseGPIOInterface):

    CHAR_GPIO_DEV_NAME = 'gpiochip'

    def __init__(self):
        self.sysfs_mode = not self.char_gpio_available()
        self.pin_map = GPIOMap()
        super().__init__()

    def setup_gpio(self, pull_str=None, trigger_str=None, _=None):
        return True
    
    def char_gpio_available(self):
        for filename in os.listdir('/dev'):
            if self.CHAR_GPIO_DEV_NAME in filename:
                return True
        return False
    
    def setup_input(self, pin_number, pull):
        try:
            kwargs = {}
            if pull:
                if not "pull" in pull:
                    pull = "pull_" + pull
                kwargs['bias'] = pull
            if self.sysfs_mode:
                self.logger.info(f'Using GPIO pin{pin_number} as input in sysfs mode')
                line_number = self.pin_map.get_chip_line(pin_number)
                return GPIO(line_number, "in", **kwargs)
            else:
                self.logger.info(f'Using GPIO pin{pin_number} as input in chardev mode')
                return GPIO(*self.pin_map.get_cgpio_dev_and_line(pin_number), "in", **kwargs)
        except:
            self.enabled = False
            self.logger.exception(f'Error on setup of GPIO pin number {pin_number}')

    def read_level(self, pin_number):
        try:
            return self.in_pins[pin_number]['handle'].read()
        except Exception as e:
            self.logger.error(f'Error on read GPIO pin number {pin_number}')
            self.enabled = False

    def close(self):
        self.enabled = False
        for pin_number in self.in_pins:
            try:
                self.in_pins[pin_number]['handle'].close()
            except:
                self.logger.error(f'Error on close GPIO pin number {pin_number}')



if __name__ == "__main__":
    per_inter = PeripheryGPIOInterface()
