import logging
import os
import pprint

import config
from base_detector import BaseDetector


class KlipperDetector(BaseDetector):

    CONFLICTS = ['USBDetector']
    OLD_DEFAULT_PORT = '/tmp/printer'
    NEW_DEFAULT_PORT = '/run/klipper/sock'
    DEFAULT_PRINTER_ID_DICT = {'VID': 'KLPR', 'PID': 'KLPR', 'SNR': None, 'COM': None}
    DEFAULT_SNR = '0'

    def __init__(self, _=None):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.printer_ids = []
        multi_klipper = config.get_settings()['klipper'].get('multi', False)
        if config.get_settings()['klipper'].get('enabled'):
            custom_ports = config.get_settings()['klipper'].get('custom_ports')
            legacy_port = config.get_settings()['klipper'].get('host_port') or config.get_settings()['klipper'].get('custom_port')
            if custom_ports:
                for custom_port in custom_ports:
                    if self.port_exists(custom_port):
                        self.fill_printerid(custom_port)
                        if not multi_klipper:
                            break
            if not self.printer_ids:
                if self.port_exists(legacy_port):
                    self.fill_printerid(legacy_port)
                else:
                    for port in (self.OLD_DEFAULT_PORT, self.NEW_DEFAULT_PORT):
                        if self.port_exists(port):
                            self.fill_printerid(port)
                            if not multi_klipper:
                                break
        if self.printer_ids:
            self.logger.info('Klipper ports detected:\n' + pprint.pformat(self.printer_ids))

    def fill_printerid(self, port):
        printerid_dict = {}
        printerid_dict.update(self.DEFAULT_PRINTER_ID_DICT)
        snr = port.replace("/", "_").replace("~", "_")
        if config.get_settings()['klipper'].get('unique_snr', False):
            printerid_dict['SNR'] = snr[:80]
        else:
            printerid_dict['SNR'] = self.DEFAULT_SNR
        printerid_dict['COM'] = os.path.expanduser(port)
        self.printer_ids.append(printerid_dict)

    def port_exists(self, port):
        if port and isinstance(port, str):
            try:
                port = os.path.expanduser(port)
                return os.path.islink(port) or os.path.isfile(port)
            except:
                pass
        return False

    def get_printers_list(self):
        return self.printer_ids

if __name__ == "__main__":
    kd = KlipperDetector()
    print(kd.get_printers_list())
