#!/usr/bin/env python3

import argparse
import os
import signal
import subprocess
import sys
import time

REAL_PATH = __file__

for i in range(20):
    if os.path.islink(REAL_PATH):
        print(f"Replacing symlink: {REAL_PATH}")
        REAL_PATH = os.readlink(REAL_PATH)
    else:
        break

if os.path.islink(REAL_PATH):
    print("You clearly messed something up, what are you trying to do?")
    exit(1)

VERSION = "stargate"

def parse_args():
    parser = argparse.ArgumentParser(
        description="Launch Stargate DAW",
    )
    parser.add_argument(
        'project_file',
        default=None,
        help='The project file to open',
        nargs='?',
    )
    parser.add_argument(
        '--create',
        action='store_true',
        default=False,
        dest='create',
        help='Create the project if it does not exist',
    )
    args = parser.parse_args()
    if args.project_file is not None:
        assert os.path.basename(args.project_file) == f'{VERSION}.project', (
            f"File must be in the format '/path/to/{VERSION}.project', "
            f"got '{args.project_file}'"
        )
        assert args.create or os.path.isfile(args.project_file), \
            f"{args.project_file} does not exist"
    return args

def qt_message_handler(mode, context, message):
    line = (
        f'qt_message_handler: {mode} '
        f'{context.file}:{context.line}:{context.function}'
        f' "{message}"'
    )
    if mode == QtCore.QtMsgType.QtWarningMsg:
        LOG.warning(line)
    elif mode in (
        QtCore.QtMsgType.QtCriticalMsg,
        QtCore.QtMsgType.QtFatalMsg,
    ):
        LOG.error(line)
    else:
        LOG.info(line)

def _setup():
    global LOG, QtCore, QApplication
    from sglib.log import LOG, setup_logging
    setup_logging()
    LOG.info(f"sys.argv == {sys.argv}")
    from sgui.sgqt import QApplication, QGuiApplication, QtCore
    QtCore.qInstallMessageHandler(qt_message_handler)
    from sgui.util import setup_theme
    try:
        QGuiApplication.setHighDpiScaleFactorRoundingPolicy(
            QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough,
        )
    except Exception as ex:
        LOG.warning(
            "Unable to set "
            "QGuiApplication.setHighDpiScaleFactorRoundingPolicy"
            f" {ex}"
        )
    app = QApplication(sys.argv)
    scaler = setup_theme(app)
    return app, scaler

def start_paulstretch():
    from sglib.lib.paulstretch import main as ps_main
    ps_main()

def start_stargate():
    app, scaler = _setup()
    from sglib.constants import UI_PIDFILE
    from sglib.lib.pidfile import check_pidfile, create_pidfile
    args = parse_args()
    pid = check_pidfile(UI_PIDFILE)
    if pid is not None:
        from sgui.sgqt import QMessageBox
        QMessageBox.warning(
            None,
            "Error",
            f"Detected Stargate is already running with pid {pid}, "
            "please close the other instance first",
        )
        sys.exit(0)
    create_pidfile(UI_PIDFILE)
    if not args.project_file:
        from sgui.welcome import Welcome
        w = Welcome(app, scaler)
        app.exec()
        if not w.loaded:
            os.remove(UI_PIDFILE)
            sys.exit(0)
    # Refresh the app we just exec'd
    app = QApplication(sys.argv)
    from sgui.splash import SplashScreen
    splash_screen = SplashScreen(scaler.y_res)
    from sgui.main import main
    main(app, splash_screen, scaler, args.project_file)

def main():
    # When respawning, give the old process a chance to garbage collect first
    if "--delay" in sys.argv:
        sys.argv.remove("--delay")
        time.sleep(1)

    is_paulstretch = False
    if len(sys.argv) >= 2 and sys.argv[1] == 'paulstretch':
        is_paulstretch = True
        sys.argv.pop(1)

    f_prefix_dir = os.path.dirname(REAL_PATH)
    f_path = os.path.join(
        f_prefix_dir,
        "..",
    )
    f_path = os.path.abspath(f_path)
    print(f'Adding PYTHONPATH {f_path}')
    sys.path.insert(0, f_path)
    try:
        if is_paulstretch:
            start_paulstretch()
        else:
            start_stargate()
        return
    except ImportError:
        print(
            "Did not detect local development environment, trying "
            "system installation",
        )
    f_path = os.path.join(
        f_prefix_dir,
        "..",
        "share",
        VERSION,
        "stargate",
    )
    f_path = os.path.abspath(f_path)
    print(f'Adding PYTHONPATH {f_path}')
    sys.path.insert(0, f_path)
    if is_paulstretch:
        start_paulstretch()
    else:
        start_stargate()

if __name__ == "__main__":
    main()
