import locale
import os
import platform
import shutil
import sys
import traceback

from PyQt5.QtCore import QCoreApplication, QTranslator, QUrl, QUrlQuery, PYQT_VERSION_STR
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtGui import QDesktopServices

import OpenNumismat
from OpenNumismat.Settings import Settings
from OpenNumismat.MainWindow import MainWindow
from OpenNumismat.Tools import TemporaryDir
from OpenNumismat import version


def main():
    try:
        locale.setlocale(locale.LC_ALL, '')
    except:
        # Work around system locale not specified (under Linux or Mac OS)
        pass

    app = QApplication(sys.argv)

    QCoreApplication.setOrganizationName(version.Company)
    QCoreApplication.setApplicationName(version.AppName)

    settings = Settings()
    if settings['error']:
        sys.excepthook = exceptHook

    if not os.path.exists(settings['reference']):
        # Create default dirs and files if not exists
        try:
            ref_path = os.path.dirname(settings['reference'])
            dst_ref = os.path.join(ref_path, 'reference.ref')
            if not os.path.exists(dst_ref):
                os.makedirs(ref_path, exist_ok=True)
                src_ref = os.path.join(OpenNumismat.PRJ_PATH, 'db',
                                   'reference_%s.ref' % settings['locale'])
                if not os.path.exists(src_ref):
                    src_ref = os.path.join(OpenNumismat.PRJ_PATH, 'db',
                                       'reference_en.ref')

                shutil.copy(src_ref, dst_ref)

            dst_demo_db = os.path.join(OpenNumismat.HOME_PATH, 'demo.db')
            if not os.path.exists(dst_demo_db):
                os.makedirs(OpenNumismat.HOME_PATH, exist_ok=True)
                src_demo_db = os.path.join(OpenNumismat.PRJ_PATH, 'db',
                                           'demo_%s.db' % settings['locale'])
                if not os.path.exists(src_demo_db):
                    src_ref = os.path.join(OpenNumismat.PRJ_PATH, 'db',
                                       'demo_en.ref')

                shutil.copy(src_demo_db, dst_demo_db)
        except:
            pass

    TemporaryDir.init(version.AppName)

    lang = settings['locale']

    translator = QTranslator()
    translator.load('lang_' + lang, OpenNumismat.PRJ_PATH)
    app.installTranslator(translator)

    translatorQt = QTranslator()
    translatorQt.load('qtbase_' + lang, OpenNumismat.PRJ_PATH)
    app.installTranslator(translatorQt)

    mainWindow = MainWindow()
    mainWindow.show()
    mainWindow.raise_()  # this will raise the window on Mac OS X
    status = app.exec_()

    # Clear temporary files
    TemporaryDir.remove()

    sys.exit(status)


def exceptHook(type_, value, tback):
    stack = ''.join(traceback.format_exception(type_, value, tback))

    title = QApplication.translate("ExcpHook", "System error")
    text = QApplication.translate("ExcpHook",
                        "A system error occurred.\n"
                        "Do you want to send an error message to the author\n"
                        "(Google account required)?")
    msgBox = QMessageBox(QMessageBox.Information, title, text)
    msgBox.setDetailedText(stack)
    msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
    if msgBox.exec_() == QMessageBox.Yes:
        line = traceback.extract_tb(tback, 1)[0]
        subject = "[v%s] %s - %s:%d" % (version.Version, type_.__name__,
                                        line[0], line[1])

        errorMessage = []
        errorMessage.append("%s: %s" % (version.AppName, version.Version))
        errorMessage.append("OS: %s %s %s (%s)" % (platform.system(),
                                                   platform.release(),
                                                   platform.architecture()[0],
                                                   platform.version()))
        errorMessage.append("Python: %s" % platform.python_version())
        errorMessage.append("Qt: %s" % PYQT_VERSION_STR)
        errorMessage.append('')
        errorMessage.append(stack)

        url = QUrl('https://code.google.com/p/open-numismat/issues/entry')
        query = QUrlQuery()
        query.addQueryItem('summary', subject)
        query.addQueryItem('comment', '\n'.join(errorMessage))
        url.setQuery(query)

        executor = QDesktopServices()
        executor.openUrl(url)

    # Call the default handler
    sys.__excepthook__(type_, value, tback)

if __name__ == '__main__':
    main()
