# 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 pprint
import signal

import config
import log
import paths

from base_app import BaseApp

try:
    import rights
except ImportError:
    rights = None

from camera_controller import CameraController
from client_scanner import ClientScanner
from detection_wizard import DetectionWizard
from gpio_uart_detect import GPIOUARTDetector
from klipper_detect import KlipperDetector
from local_moonraker_detector import LocalMoonrakerDetector
from makerware_utils import ConveyorKillWaiter
from network_detect import NetworkDetector
from plugin_controller import PluginController
from rights import RightsChecker
from tray_controller import TrayController
from updater import Updater
from usb_detect import USBDetector
from dnsmasq_detector import DNSMasqDetector
from no_subproc_camera_controller import NoSubprocCameraController
from static_and_stored_detect import StaticDetector
from user_login import UserLogin


class App(BaseApp):

    @log.log_exception
    def init_adv(self):
        if self.platform_warnings_enabled:
            self.warnings.extend(self.get_for_platfrom_flaws())
        if rights:
            restart = rights.add_cacert_to_certifi()
            if restart:
                self.logger.warning('Scheduling a restart to apply a new certificate')
                self.restart_flag = True
                self.stop_flag = True
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        try:
            self.plugin_controller = PluginController(self)
        except NameError:
            pass
        try:
            self.rights_checker = RightsChecker(self)
        except NameError:
            pass
        try:
            self.conveyor_kill_waiter = ConveyorKillWaiter(self)
        except NameError:
            pass
        self.user_login = UserLogin(self, retry_in_background=config.get_settings()['pre_login_ui'])
        config.Config.instance().set_profiles(self.user_login.profiles)
        if self.settings['camera']["no_subprocess"]:
            self.camera_controller = NoSubprocCameraController(self)
        else:
            self.camera_controller = CameraController(self)
        self.updater = Updater(self)
        if not self.offline_mode:
            self.updater.start_checks_loop()
        self.client_scanner = ClientScanner(self)
        self.tray_controller = TrayController()
        self.detection_wizard = DetectionWizard(self)
        self.init_user_interfaces()
        try:
            with open(paths.JOB_STARTS, 'w') as f:
                f.write('')
        except OSError:
            pass
        for detector_class in (GPIOUARTDetector, LocalMoonrakerDetector, KlipperDetector, USBDetector, NetworkDetector, StaticDetector, DNSMasqDetector):
            self.detectors[detector_class.__name__] = detector_class(self)
        self.logger.info('Detectors: ' + pprint.pformat(self.detectors.keys()))
        if self.settings['web_interface']['browser_opening_on_start'] and self.settings['pre_login_ui']:
            self.open_browser()
        if self.user_login.wait() and self.rights_checker.wait() and self.conveyor_kill_waiter.wait():
            if self.settings['web_interface']['browser_opening_on_start'] and not self.settings['pre_login_ui']:
                self.open_browser()
            self.camera_controller.start_camera_process()
            config.Config.instance().set_profiles(self.user_login.profiles)
            virtual_printer = self.settings['virtual_printer']
            self.virtual_printer_enabled = virtual_printer['enabled']
            self.virtual_printer_usb_info = dict(virtual_printer)
            del self.virtual_printer_usb_info['enabled']
            self.host_commands_enabled = self.settings.get('host_commands')
