# Copyright 3D Control Systems, Inc. All Rights Reserved 2017-2019.

# Built in San Francisco.

# This software is distributed under a commercial license for personal,
# educational, corporate or any other use.
# The software as a whole or any parts of it is prohibited for distribution or
# use without obtaining a license from 3D Control Systems, Inc.

# All software licenses are subject to the 3DPrinterOS terms of use
# (available at https://www.3dprinteros.com/terms-and-conditions/),
# and privacy policy (available at https://www.3dprinteros.com/privacy-policy/)

import upnpy

import base_scanner

class UPNPDetector(base_scanner.Scanner):

    PORT = 80 # port is not real port on which unpnp responded, but port belong to printer's API
    TIMEOUT = 6
    SERVICES_FILTER = [] #empty means use all
    LOG_ALL = False 

    def __init__(self, parent=None, profile=None, conn=None):
        super().__init__(parent, profile, conn)
        self.log_all = self.LOG_ALL

    def filter_by_service_name(self, services):
        if self.SERVICES_FILTER:
            for service_name in services:
                if service_name in self.SERVICES_FILTER:
                    break
            else:
                return False
        return True

    def detect(self, already_know_ip=None, non_default_port=None):
        if non_default_port:
            self.port = non_default_port
        try:
            upnp = upnpy.UPnP()
            upnp.discover()
        except ImportError:
            self.logger.error("Unable to import upnpy library")
        except:
            self.logger.error("Upnpy internal error")
        else:
            for discovered in upnp.discovered_devices:
                ip = discovered.host
                if self.log_all:
                    self.logger.warning('Discovered: ' + str(discovered))
                if self.filter_by_service_name(discovered.services):
                    if self.check_ip(ip):
                        self.logger.info(f"Adding printer: {ip}")
                        discovered_host = {"IP": ip, "PORT": self.port, "SNR": ip}
                        self.discovered_printers.append(discovered_host)
                    else:
                        self.logger.debug(f"Skipping host(printer check failed): {ip}")
                else:
                    self.logger.debug(f'No target upnp services found on {ip} - skipping')

    def check_ip(self, host):
        self.logger.warning(f"A real check_ip is not implemented for {__class__.__name__}!")
        return True


if __name__ == "__main__":
    import pprint

    detector = UPNPDetector()
    detector.log_all = True
    pprint.pprint(detector.detect())
