# -*- coding: utf-8 -*-

# -----------------------------------------------------------------------------
# Copyright 2016 Anaconda, Inc.
#
# May be copied and distributed freely only as part of an Anaconda or
# Miniconda installation.
# -----------------------------------------------------------------------------

"""Application start."""

from __future__ import annotations

import argparse
import signal
import sys
import types
import typing

from qtpy.QtCore import QCoreApplication, Qt
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QApplication

from navigator_updater.config import LOCKFILE
from navigator_updater.external import filelock
from navigator_updater.static import images
from navigator_updater.static.fonts import load_fonts
from navigator_updater.utils.logs import setup_logger, LOGGER_CONFIG
from navigator_updater.utils.qthelpers import qapplication
from navigator_updater.utils.styles import load_style_sheet
from navigator_updater.widgets.dialogs import MessageBoxInformation
from navigator_updater.widgets.dialogs.main_dialog import MainDialog


# For retina displays on qt5
if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
    QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
if hasattr(Qt, 'AA_EnableHighDpiScaling'):
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)


def except_hook(cls: type[BaseException], exception: BaseException, traceback: types.TracebackType | None) -> None:
    """Custom except hook to avoid crashes on PyQt5."""
    sys.__excepthook__(cls, exception, traceback)


def start_app(options: argparse.Namespace) -> typing.NoReturn:  # pragma: no cover
    """Main application entry point."""
    LOGGER_CONFIG.level = options.log_level
    setup_logger()

    # Monkey patching sys.excepthook to avoid crashes in PyQt 5.5+
    sys.excepthook = except_hook

    application: QApplication = qapplication(test_time=60)
    application.setWindowIcon(QIcon(images.ANACONDA_LOGO))
    load_fonts(application)
    application.setStyleSheet(load_style_sheet())

    signal.signal(signal.SIGINT, signal.SIG_DFL)

    try:
        with filelock.FileLock(LOCKFILE).acquire(timeout=1.0):  # type: ignore
            dialog: MainDialog = MainDialog()
            application.window = dialog
            sys.exit(dialog.exec_())
    except filelock.Timeout:  # type: ignore
        sys.exit(
            MessageBoxInformation(
                title='Anaconda Navigator Updater Information',
                text='There is an instance of Anaconda Navigator Updater already running.',
            ).exec_(),
        )
