#!/usr/bin/python3
"""StartWine gdbus call wrapper and commandline parser."""

import os
from sys import argv
from pathlib import Path
from subprocess import run, PIPE
from multiprocessing import Process
import time


def get_sw_scripts_path():
    """Get current StartWine scripts path"""

    argv0 = os.getenv('ARGV0')
    sw_rt = Path(argv0).absolute().parent.parent if (argv0 is not None and argv0 != '') else None
    sw_rc = swrc.read_text(encoding="utf-8").splitlines()[0] if swrc.exists() else None

    if sw_rt is not None and Path(f'{sw_rt}/scripts/sw_menu.py').exists():
        _sw_scripts = Path(f'{sw_rt}/scripts')

    elif sw_rc is not None and Path(f'{sw_rc}/data/scripts/sw_menu.py').exists():
        _sw_scripts = Path(f'{sw_rc}/data/scripts')

    elif Path(f'{sw_default_path}/StartWine/data/scripts/sw_menu.py').exists():
        _sw_scripts = Path(f'{sw_default_path}/StartWine/data/scripts')

    else:
        _sw_scripts = Path(argv[0]).absolute().parent

    print('SW_SCRIPTS_PATH:', _sw_scripts)
    return _sw_scripts


swrc = Path(f'{Path.home()}/.config/swrc')
sw_default_path = Path(f'{Path.home()}/.local/share')
sw_scripts = os.getenv('SW_SCRIPTS_PATH')

if sw_scripts is None or sw_scripts == '':
    sw_scripts = get_sw_scripts_path()

sw_menu = Path(f"{sw_scripts}/sw_menu.py")
sw_crier = Path(f"{sw_scripts}/sw_crier.py")
sw_tray = Path(f"{sw_scripts}/sw_tray.py")
sw_shell = Path(f"{sw_scripts}/sw_term_shell.py")

################################___START___:

CMD_SHOW = 'gdbus call -e --dest ru.project.StartWine \
--object-path /ru/project/StartWine --method ru.project.StartWine.Show "None"'

CMD_RUN = 'gdbus call -e --dest ru.project.StartWine \
--object-path /ru/project/StartWine --method ru.project.StartWine.Run "None"'

CMD_ACTIVE = 'gdbus call -e --dest ru.project.StartWine \
--object-path /ru/project/StartWine --method ru.project.StartWine.Active "active"'


def init_icon_theme():
    """Initialize system icons theme."""

    cmd_icon_theme = 'shellsrv gsettings get org.gnome.desktop.interface icon-theme'
    out = run(
            f'/bin/bash -c "{cmd_icon_theme}" 2>/dev/null',
            shell=True, stdout=PIPE, encoding='UTF-8', check=False
    )
    if len(out.stdout.splitlines()) > 0:
        os.environ['SW_GTK_ICON_THEME'] = out.stdout.splitlines()[0].strip("'")
        print('SW_GTK_ICON_THEME:', out.stdout.splitlines()[0].strip("'"))


def silent_start(x_arg):
    """Running the menu in silent mode."""

    if x_arg is None:
        status = run(f'"{sw_menu}" "--silent"', shell=True, check=False)
    else:
        status = run(f'"{sw_menu}" "--silent" "{x_arg}"', shell=True, check=False)

    return status

def gdbus_run(x_arg, x_cmd):
    """Running by calling gdbus."""

    if x_arg is not None:
        x_arg = x_arg.replace("'", '**')

    if x_cmd == CMD_SHOW:
        x_cmd = f'gdbus call -e --dest ru.project.StartWine \
        --object-path /ru/project/StartWine --method ru.project.StartWine.Show \
        "{x_arg}"'

    if x_cmd == CMD_RUN:
        x_cmd = f'gdbus call -e --dest ru.project.StartWine \
        --object-path /ru/project/StartWine --method ru.project.StartWine.Run \
        "{x_arg}"'

    return run(f"/bin/bash -c '{x_cmd}' 2>/dev/null", shell=True, check=False)


def on_start(x_arg, x_cmd):
    """Starting a new process with initialization of the launch method."""

    out = run(
            f'/bin/bash -c "{CMD_ACTIVE}" 2>/dev/null',
            shell=True, stdout=PIPE, encoding='UTF-8', check=False
    )
    if out.stdout == '':
        p = Process(target=silent_start, args=(x_arg,))
        p.start()
        out = ''
        while out == '':
            out = run(
                    f'/bin/bash -c "{CMD_ACTIVE}" 2>/dev/null',
                    shell=True, stdout=PIPE, encoding='UTF-8', check=False
            ).stdout
            time.sleep(0.1)

        if x_cmd == '--run':
            Process(target=gdbus_run, args=(x_arg, CMD_RUN)).start()
        else:
            Process(target=gdbus_run, args=(x_arg, CMD_SHOW)).start()

    else:
        if x_cmd == '--run':
            Process(target=gdbus_run, args=(x_arg, CMD_RUN)).start()
        else:
            Process(target=gdbus_run, args=(x_arg, CMD_SHOW)).start()


def on_cube():
    """Running the StartWine OpenGL cube."""

    return run('mangohud --dlsym cube -v', shell=True, check=False)


def on_tray():
    """Running the StartWine tray."""

    return run(f'"{sw_tray}"', shell=True, check=False)


def on_shell():
    """Running the StartWine terminal shell."""

    return run(f'"{sw_shell}"', shell=True, check=False)


def on_crier(x_args):
    """Running the StartWine Crier dialogs."""

    return run(f"{sw_crier} {x_args}", shell=True, check=False)


def on_helper():
    """commandline help info"""

    sw_start_help = '''
    -c or --cube                          running opengl cube
    -t or --tray                          running StartWine in tray
    -d or --dialog ('-h' for print help)  running dialogs with message
    -p or --path                          running StartWine path chooser
    -h or --help                          print this help info and exit
    '''
    print(sw_start_help)


if __name__ == '__main__':

    init_icon_theme()

    if len(argv) == 1:
        on_start(None, None)

    elif len(argv) > 1:

        if argv[1] == '--cube' or argv[1] == '-c':
            on_cube()

        elif argv[1] == '--tray' or argv[1] == '-t':
            on_tray()

        elif argv[1] == '--shell' or argv[1] == '-s':
            on_shell()

        elif argv[1] == '--dialog' or argv[1] == '-d':
            if len(argv) > 2:
                on_crier(argv[2])
            else:
                on_helper()

        elif argv[1] == '--path' or argv[1] == '-p':
            if len(argv) > 2:
                on_crier('-p ' + str(argv[2]))
            elif len(argv) == 2:
                on_crier('-p ' + str(sw_default_path))
            else:
                on_helper()

        elif argv[1] == '--help' or argv[1] == '-h':
            on_helper()

        else:
            if len(argv) > 2:
                on_start(argv[1], argv[2])
            else:
                on_start(argv[1], None)
