#!/usr/bin/env python3

import os
import sys
import shutil
import threading
import subprocess

from typing import Optional

# Import core utils without download dependencies
from corenodep import (
    join_lists_with_delimiter,
    split_list_by_delimiter,
    load_conf_setting,
    save_conf_setting,
    parse_version,
    read_file,
    winpath,
)

# Import core utils
from coreutils import (
    exit_with_message,
    script_manager,
    popup_options,
    show_message,
    monitor_file,
    cache,
    log,
)

# Import main utils
from mainutils import (
    find_closest_compatible_release,
    unpack_zip_with_progress,
    get_github_releases,
    flatpakrunner,
    popup_execute,
    popup_download,
    get_dotnet48,
    deref,
)

# Import from setup
from setup import (
    check_flatpak,
    venv_manager,
    self_update,
    setup_main,
)


if getattr(sys, "frozen", False):
    SCRIPT_FILE = os.path.realpath(sys.executable)
else:
    SCRIPT_FILE = os.path.realpath(__file__)
SCRIPT_PATH = os.path.dirname(SCRIPT_FILE)


# Fist main block of two
if __name__ == "__main__":
    # Print version and update config
    script_manager()
    # Make venv if needed andreturn path
    python_venv = venv_manager()
    # Update the script
    python_venv = self_update(python_venv)
    # Detect if the script is running inside a flatpak
    if_flatpak_list = check_flatpak(python_venv)

    # On venv path restart the script
    if bool(if_flatpak_list):
        # Use environment varible to protect the script from re-running forever
        inf_protect = os.getenv("WeModInfProtect", "1")
        if int(inf_protect) > 4:
            exit_with_message(
                "Infinite rerun",
                "Infinite script reruns were detected\nThe script was stoped\nCreate a issue on the wemod_laucher github\nand add this file to the issue",
            )
        os.environ["WeModInfProtect"] = str(int(inf_protect) + 1)

        # if we are in a flatpak we wait for a command to be passed back into the script in a thread
        if len(if_flatpak_list) > 1:
            flat_thread = threading.Thread(target=flatpakrunner)
            flat_thread.start()

        command = if_flatpak_list + [SCRIPT_FILE] + sys.argv[1:]
        log(
            f"Re-running script within virtual environment \nor to update or to run outside of flatpak with the command:\n\t{command}\n\nThe rerun nr {inf_protect} was started"
        )

        # Execute the script within the virtual environment
        try:
            process = subprocess.run(command, capture_output=True, text=True)
            print(str(process.stdout))
            print(str(process.stderr))
        except Exception as e:
            log(f"Unknown rerun command error:\n\t{e}")
            exit_with_message(
                "Unknown Command error",
                f"The command to rerun the script failed becalse the command returned an unknown error:\n\t{e}\nYou are probably using flatpak,\nif that is the case install flatpak-xdg-utils\nand allow system and session bus in flatseal",
            )

        if len(if_flatpak_list) > 1:
            flat_thread.join()

        # exit after it was run in a venv succesfully
        sys.exit(process.returncode)


# Import utils that need constants
from constutils import (
    scanfolderforversions,
    troubleshooter,
    enshure_wine,
    winetricks,
    wine,
)


# Import consts
from consts import (
    BASE_STEAM_COMPAT,
    BAT_COMMAND,
    STEAM_COMPAT_FOLDER,
    WINEPREFIX,
    INIT_FILE,
)


# Symlink wemod data to make all wemod prefixes use the same wemod data
def syncwemod(
    folder: Optional[str] = None,
) -> None:
    response = None
    package_prefix = os.getenv(
        "PACKAGEPREFIX"
    )  # use PACKAGEPREFIX=true in front of the command to generate a ge-proton-prefix zip and exit
    if not package_prefix:
        package_prefix = load_conf_setting("PackagePrefix")
        if package_prefix:
            if package_prefix.lower() != "true":
                try:
                    package_prefix = int(package_prefix)
                except Exception as e:
                    package_prefix = "false"
                else:
                    if package_prefix > 0:
                        package_prefix -= 1
                        save_conf_setting("PackagePrefix", package_prefix)
                        package_prefix = "true"
    if package_prefix and folder == None and package_prefix.lower() == "true":
        from mainutils import copy_folder_with_progress

        log(
            "Prefix packaging was requested with PACKAGEPREFIX=true in front of the command"
        )
        current_proton_version = read_file(
            os.path.join(BASE_STEAM_COMPAT, "version")
        )
        if not current_proton_version:
            log(f"Version is not set for {BASE_STEAM_COMPAT}, Error")
            exit_with_message(
                "Prefix Version unknown",
                "The prefix version is unknown, please make shure the prefix works with WeMod before trying to zip it",
                timeout=20,
            )
        cut_proton_version = parse_version(current_proton_version)
        destfile = os.path.join(
            STEAM_COMPAT_FOLDER,
            "prefixes",
            "GE-Proton"
            + str(cut_proton_version[0])
            + "."
            + str(cut_proton_version[1])
            + ".zip",
        )

        if not os.path.isfile(INIT_FILE):
            log(f"WeMod is not installed in {BASE_STEAM_COMPAT}, Error")
            exit_with_message(
                "WeMod not installed",
                "WeMod is not installed in the active prefix, exiting",
                timeout=20,
            )

        os.makedirs(os.path.dirname(destfile), exist_ok=True)

        if os.path.isfile(destfile):
            os.remove(destfile)

        log(f"Zipping folder '{BASE_STEAM_COMPAT}' into '{destfile}'")

        initcont = read_file(INIT_FILE)
        with open(INIT_FILE, "w") as init:
            init.write("")

        waslink = False
        if os.path.islink(WINEPREFIX):
            os.remove(WINEPREFIX)
            waslink = True

        copy_folder_with_progress(
            BASE_STEAM_COMPAT, destfile, True, [None], [None]
        )

        if waslink:
            try:
                os.symlink(BASE_STEAM_COMPAT, WINEPREFIX)
            except Exception as e:
                pass

        with open(INIT_FILE, "w") as init:
            init.write(initcont)

        os.system(
            "xdg-open '" + os.path.join(STEAM_COMPAT_FOLDER, "prefixes") + "'"
        )
        log("Done creating Prefix zip")
        exit_with_message(
            "Prefix Packaged",
            "The prefix was zipped succesfully, exiting",
            timeout=5,
        )

    if folder == None:
        folder = BASE_STEAM_COMPAT

    WeModData = os.path.join(SCRIPT_PATH, "wemod_data")  # link source
    WeModExtenal = os.path.join(
        folder, "pfx/drive_c/users/steamuser/AppData/Roaming/WeMod"
    )  # link dest

    log(
        f"Syncing wemod data from '{WeModExtenal}' to laucher dir '{WeModData}'"
    )
    if not os.path.isdir(WeModData):
        os.makedirs(WeModData)  # Make wemod data folder if missing
    if not os.path.isdir(WeModExtenal):
        os.makedirs(WeModExtenal)
    if os.path.isdir(WeModExtenal) and not os.path.islink(
        WeModExtenal
    ):  # If the extenal data exist
        if (
            len(os.listdir(WeModData)) > 0
            and len(os.listdir(WeModExtenal)) > 0
        ):  # If wemod folder and extenal folder are not empty
            # We ask what files to use

            response = show_message(
                f"Warnig wemod might have been installed previously.\nUse wemod laucher dir account (Yes) or\nUse wemod prefix/game dir account (No)",
                title="Multiple accounts found",
                yesno=True,
            )
        if (response == "No" or len(os.listdir(WeModData)) == 0) and len(
            os.listdir(WeModExtenal)
        ) > 0:
            log("The local wemod data was requested to be overwritten")
            shutil.rmtree(WeModData)
            shutil.copytree(
                WeModExtenal, WeModData
            )  # We copy from game if the user selects or if data is empty
        shutil.rmtree(WeModExtenal)  # Remove wemod data from game
    if not os.path.isdir(WeModExtenal) and not os.path.islink(WeModExtenal):
        os.symlink(
            WeModData, WeModExtenal
        )  # And symlink the data from the wemod laucher
        log("Linked wemod data to gameprefix")

    if not os.path.exists(
        os.path.join(SCRIPT_PATH, "wemod_bin", "WeMod.exe")
    ):
        setup_main()


# Initialize the environment
def init(proton: str, iswine: bool = False) -> None:
    # Create wineprefix directory if it doesn't exist
    if not os.path.isdir(WINEPREFIX):
        os.makedirs(BASE_STEAM_COMPAT, exist_ok=True)

    # Grab active proton version
    if iswine:
        os.environ["WINEPREFIX"] = BASE_STEAM_COMPAT

        try:
            wver = subprocess.run(
                [proton, "--version"],
                bufsize=1,
                capture_output=True,
                text=True,
            )
        except Exception as e:
            log(
                f"Problem grabing the external wine version, using file, returned was:\n\t{e}"
            )
            prefix_version_file = enshure_wine()
        else:
            prefix_version_file = enshure_wine(str(wver.stdout))
    else:
        prefix_version_file = enshure_wine()
    current_proton_version = read_file(prefix_version_file)
    current_version_parts = parse_version(current_proton_version)
    if current_version_parts == None:
        exit_with_message(
            "Missing proton version",
            f"Error, the GE-Proton version file could not be read, its at:\n'{prefix_version_file}'.\nTry to delete the game prefix at:\n'{BASE_STEAM_COMPAT}'",
            timeout=30,
            ask_for_log=True,
        )

    # If wemod is not installed try to copy a working prefix to the current one
    log(f"Looking for init file '{INIT_FILE}'")
    if not os.path.exists(INIT_FILE):
        log(
            f"Loking for compatible wine prefixes in '{STEAM_COMPAT_FOLDER}' with proton version '{current_version_parts[0]}.{current_version_parts[1]}'"
        )

        # Get closest version that has wemod installed
        closest_version, closest_prefix_folder = scanfolderforversions(
            current_version_parts
        )
        cut_version = parse_version(closest_version)

        if closest_version and current_version_parts:
            log(
                f"Found was '{cut_version[0]}.{cut_version[1]}' on '{current_version_parts[0]}.{current_version_parts[1]}'"
            )

        from mainutils import copy_folder_with_progress

        response = "No"
        if (
            closest_version
            and current_version_parts
            and closest_version == current_version_parts
        ):
            response = show_message(
                f"The Proton version {current_version_parts[0]}.{current_version_parts[1]} dosn't have WeMod installed. Would you like to use the perfectly matched Proton version {cut_version[0]}.{cut_version[1]} that has WeMod installed, which is very likely going to work?",
                title="Very likely compatible WeMod version detected",
                yesno=True,
            )
            if response == None:
                response = "Yes"
        elif (
            closest_version
            and current_version_parts
            and closest_version[0] == current_version_parts[0]
        ):

            response = show_message(
                f"The Proton version {current_version_parts[0]}.{current_version_parts[1]} dosn't have WeMod installed. Would you like to use the closest proton version {cut_version[0]}.{cut_version[1]} that has WeMod installed, which is likely going to work?",
                title="Likely compatible WeMod version detected",
                yesno=True,
            )
            if response == None:
                response = "Yes"
        elif (
            closest_version
            and current_version_parts
            and closest_version[0] != current_version_parts[0]
        ):
            response = show_message(
                f"The Proton version {current_version_parts[0]}.{current_version_parts[1]} dosn't have WeMod installed. Would you like to attempt to use the closest proton version {cut_version[0]}.{cut_version[1]} that has WeMod installed, which may result in some issues?",
                title="Mabye compatible WeMod version detected",
                yesno=True,
            )
        else:
            log(
                "No compatible Proton version found in the compatibility folder."
            )
        if response == "Yes":
            # Copy the closest version's prefix to the gameprefix
            log(f"Copying {closest_prefix_folder} to {BASE_STEAM_COMPAT}")
            syncwemod(
                closest_prefix_folder
            )  # Sync wemod data in closest version

            copy_folder_with_progress(
                closest_prefix_folder,
                BASE_STEAM_COMPAT,
                False,
                [None],
                [None],
            )
            syncwemod()  # Sync wemod data
            log(
                f"Copied Proton version {cut_version[0]}.{cut_version[1]} prefix to game prefix that was on version {current_version_parts[0]}.{current_version_parts[1]}"
            )
        elif closest_version and current_version_parts:
            log(
                f"User chose not to use an alternative Proton version, the active version was {current_version_parts[0]}.{current_version_parts[1]}."
            )
        else:
            log(f"No versions to copy available")

    # Check for the initialization file in the wineprefix
    log(f"Looking once more for the init file")
    if os.path.exists(INIT_FILE):
        syncwemod()  # Sync wemod data and prefix packaging
        log("Found init file. Continuing launch...")
        return

    log("Init file not found! Attempting to prepare the WINEPREFIX")

    # User choice for prefix setup
    prefix_op = popup_options(
        "Prefix Setup",
        "Would you like to download (RECOMMENDED, faster and works on all systems) an already setup one \nor build/modify (only works on some systems) your prefix?",
        [["download", "build"]],
    )

    # Determine proton directory

    proton_dir = os.path.join(os.path.dirname(proton), "files", "bin")
    log(f"Using wine from Proton at path: '{proton_dir}'")

    # Call appropriate function based on user choice
    if prefix_op and prefix_op == "build":
        build_prefix(proton_dir)
    else:
        download_prefix(proton_dir)
    syncwemod()  # Sync wemod data


# Function to download and unpack a pre-configured wineprefix
def download_prefix(proton_dir: str) -> None:
    # Check and prepare for first launch
    if not os.path.exists(WINEPREFIX + "/drive_c"):
        log(WINEPREFIX)
        exit_with_message(
            "First Launch",
            "First Launch Detected: Please run the game once without wemod first. Error.",
            ask_for_log=True,
        )

    repo_user = load_conf_setting("RepoUser")
    if not repo_user:
        repo_user = "DeckCheatz"
        # save_conf_setting("RepoUser", repo_user)
        log("RepoUser not set in config using: " + repo_user)

    repo_name = load_conf_setting("RepoName")
    if not repo_name:
        repo_name = "wemod-launcher"
        # save_conf_setting("RepoName", repo_name)
        log("RepoName not set in config using: " + repo_name)

    repo_parts = os.getenv("REPO_STRING")
    if repo_parts:
        repo_parts = repo_parts.split("/", 1) + [""]
        if repo_parts[0] and repo_parts[0] != "":
            repo_user = repo_parts[0]
        if repo_parts[1] and repo_parts[1] != "":
            repo_name = repo_parts[1]

    repo_concat = repo_user + "/" + repo_name

    current_proton_version = read_file(
        os.path.join(BASE_STEAM_COMPAT, "version")
    )
    current_version_parts = parse_version(current_proton_version)

    closest_version = None
    releases = get_github_releases(repo_concat)
    if len(releases) > 0:
        closest_version, url = find_closest_compatible_release(
            releases, current_version_parts
        )
        file_name = (
            f"wemod_prefix{closest_version[0]}.{closest_version[1]}.zip"
        )

    if (
        closest_version
        and current_version_parts
        and closest_version == current_version_parts
    ):
        response = "Yes"
    elif (
        closest_version
        and current_version_parts
        and closest_version[0] == current_version_parts[0]
    ):
        response = show_message(
            f"This is most likely going to work, the version {closest_version[0]}.{closest_version[1]} is probably compatible with version {current_version_parts[0]}.{current_version_parts[1]}, download and use it?",
            title="Likely compatible version found",
            yesno=True,
        )
        if response == None:
            response = "Yes"
    elif closest_version and current_version_parts:
        response = show_message(
            f"The current version {closest_version[0]}.{closest_version[1]} might not be compatible with version {current_version_parts[0]}.{current_version_parts[1]}, download and use it?",
            title="Mabye copatible version found",
            yesno=True,
        )
    else:
        log(
            f"There was no version to download on repo '{repo_concat}', Error..."
        )
        exit_with_message(
            "No downloads available",
            f"Error, Nothing to download on repo '{repo_concat}',\nTo fix this you can try to delete the wemod.conf",
            ask_for_log=True,
        )
    if response == "No":
        log(
            f"User was unhappy with the version download choice of {closest_version[0]}.{closest_version[1]} for {current_version_parts[0]}.{current_version_parts[1]}, exiting"
        )
        exit_with_message(
            "Closing",
            f"Closing since the download of version {closest_version[0]}.{closest_version[1]} was denied",
            timeout=5,
        )

    # Download or use cached prefix
    prefix_path = cache(
        file_name,
        lambda name: popup_download("Dowloading Prefix...", url, name),
        simple=True,
    )

    # Unpack the downloaded prefix
    log(f"Unpacking prefix file {prefix_path} into {BASE_STEAM_COMPAT}")

    unpack_zip_with_progress(prefix_path, BASE_STEAM_COMPAT)

    # Delete cache file since the prefix copyer has been added there is no need to keep this file around
    if os.path.isfile(prefix_path):
        os.remove(prefix_path)

    syncwemod()
    if not os.path.isfile(
        os.path.join(SCRIPT_PATH, "wemod_bin", "WeMod.exe")
    ):
        setup_main()

    log("Finished prefix download and unpacking")


def build_prefix(proton_dir: str) -> None:
    import FreeSimpleGUI as sg

    # Set environment path
    path = (
        os.path.join(SCRIPT_PATH, "bin")
        + ":"
        + proton_dir
        + ":"
        + os.getenv("PATH")
    )

    # deref
    winfolder = os.path.join(WINEPREFIX, "drive_c", "windows")
    log(f"Dereferencing '{winfolder}'")
    deref(winfolder)

    deps = []

    # Choose method to install dotnet48
    dotnet48_method = popup_options(
        "dotnet48",
        "Would you like to install dotnet48 with winetricks (default, for GE-Proton8 or above)\nor with wemod-launcher (ONLY USE FOR GE-Proton7)\nWARNING: The wemod-launcher option isn't working well, you can try using it anyway (ONLY ON GE-Proton7)",
        [["winetricks", "wemod-launcher"]],
    )

    # Add dependencies to the list
    deps.append("-q sdl cjkfonts vkd3d dxvk2030")

    if not dotnet48_method or dotnet48_method == "winetricks":
        deps.append("-q dotnet48")

    # Install dependencies
    log("Running dependencies installation. This could take a while...")
    setup_main()

    # Install each dependency
    resp = 0
    dep_i = -1
    while resp == 0 and (len(deps) - 1) > dep_i:
        dep_i = dep_i + 1
        resp = winetricks(deps[dep_i], path)

    # Install dotnet48 using wemod-launcher if selected
    if dotnet48_method and dotnet48_method == "wemod-launcher":
        log("Installing dotnet48...")
        dotnet48 = get_dotnet48()
        wine("winecfg -v win7", path)
        dotnet48_result = wine(dotnet48, path)

        if (
            dotnet48_result != 0
            and dotnet48_result != 194
            and dotnet48_result != -15
        ):
            exit_with_message(
                "dotnet48 install error",
                "dotnet48 installation exited with code '{}'".format(
                    dotnet48_result
                ),
                ask_for_log=True,
            )

    wine("winecfg -v win10", path)  # Set Windows version to Windows 10

    # Finalize setup
    if resp == 0:
        log("Finished dependencies installation. Writing init file...")
        open(INIT_FILE, "a").close()
    else:
        exit_with_message(
            "ERROR",
            "Failed dependencies installation with code '{}'. Aborting...".format(
                resp
            ),
            resp,
            ask_for_log=True,
        )


# Main run function
def run(skip_init: bool = False) -> str:
    # Get passed args
    ARGS = sys.argv[1:]

    tools = os.getenv("STEAM_COMPAT_TOOL_PATHS").split(os.pathsep)
    fnr = -1
    # find the first argument that has the proton tool path
    if tools:
        for tool in tools:
            for nr, aarg in enumerate(ARGS):
                if aarg and len(aarg) > 2 and aarg[0] == os.sep:
                    if tool == os.path.dirname(aarg):
                        if nr > fnr:
                            fnr = nr
                            break

    verb = ["waitforexitandrun"]
    tout = 90
    if fnr >= 0:  # if the proton tool path was found
        # Log the args for future improvment
        log(
            f"The normal args list is {len(ARGS)} long and the full contents are:\n\t{ARGS}"
        )
        # Take the start of the command
        REAPER_CMD = ARGS[:fnr]
        # Take the full proton tool path
        PROTON = ARGS[fnr]

        # If there is a file then it's a custom runner so don't use a verb
        if ARGS[(fnr + 1)].find(".") >= 0:
            fnr -= 1
            verb = []
            tout = 60

        # Get the game exe
        GAME_EXE = os.path.realpath(ARGS[(fnr + 2)])
        # Add more args at the end
        LAUNCH_OPTIONS = ARGS[(fnr + 3) :]
    else:
        # Subdivide the list into multiple lists based on delimiter
        AARGS = split_list_by_delimiter(ARGS, "--")
        # Log the args for future improvment
        log(
            f"The subsplit args list is {len(AARGS)} long and the full contents are:\n\t{AARGS}"
        )
        # Take the steam command part and merge it back into one list split by delimiter
        REAPER_CMD = join_lists_with_delimiter(AARGS[:-1], "--")
        # Add removed -- back at the end
        REAPER_CMD += ["--"]
        # Take the end that runs the game
        PROTON_CMD = AARGS[-1]
        # Take the proton path
        PROTON = PROTON_CMD[0]

        fnr = 0
        # If there is a file then it's a custom runner so don't use a verb
        if PROTON[(fnr + 1)].find(".") >= 0:
            fnr -= 1
            verb = []
            tout = 60

        # Get the game exe
        GAME_EXE = os.path.realpath(PROTON_CMD[fnr + 2])
        # Add more args at the end
        LAUNCH_OPTIONS = PROTON_CMD[(fnr + 3) :]

    # Initialize environment if not skipped
    if not skip_init:
        init(PROTON, not bool(verb))

    # Get working dir
    WORK_DIR = os.path.realpath(os.getcwd())

    if not os.path.isfile(GAME_EXE):
        log(f"Error, the game executable at '{GAME_EXE}' is missing")
        exit_with_message(
            "Game Missing",
            f"The game executable at '{GAME_EXE}' is missing.\nMake sure the game runs without WeMod.\nIf not, use 'Verify Files' in Steam or ensure the game is installed correctly.",
            ask_for_log=True,
        )

    # Make gamepath be relative to workdir (workdir is the root game dir)
    REL_EXE = os.path.relpath(GAME_EXE, WORK_DIR)

    # Make shure the relative gamepath is in windows format
    WIN_CMD = winpath(REL_EXE, addfront="")

    # Log the found parts of the command
    log(
        f"D:{WORK_DIR}\nR:{REAPER_CMD}\nP:{PROTON}\nV:{verb}\nB:{BAT_COMMAND}\nG:{WIN_CMD}\nL:{LAUNCH_OPTIONS}"
    )

    # Construct the final command
    FINAL = (
        REAPER_CMD
        + [PROTON]
        + verb
        + BAT_COMMAND
        + [WIN_CMD]
        + LAUNCH_OPTIONS
    )

    ttfile = os.path.join(SCRIPT_PATH, ".cache", "early.tmp")
    returnfile = os.path.join(SCRIPT_PATH, ".cache", "return.tmp")

    os.makedirs(os.path.dirname(ttfile), exist_ok=True)

    ttime = open(ttfile, "w")
    ttime.write("")
    ttime.close()

    log(f"Creating a game time tracking file, the file is:\n\t{ttfile}")

    ttime_thread = threading.Thread(
        target=monitor_file, args=(ttfile, tout, returnfile)
    )
    ttime_thread.start()

    # Log the final command
    log(f"Executing:\n\t{FINAL}\n")
    print(f"Executing:\n\t{FINAL}\n")

    fromflat = os.getenv("FROM_FLATPAK")

    if fromflat:
        import time

        log("Useing flatpak mode")

        cachedir = os.path.join(SCRIPT_PATH, ".cache")
        os.makedirs(cachedir, exist_ok=True)

        flatpakrunfile = os.path.join(cachedir, "insideflatpak.tmp")
        errorfile = os.path.join(cachedir, "flatpakerror.tmp")
        warnfile = os.path.join(cachedir, "flatpakwarn.tmp")

        log("Save flatpak command to, inside flatpak run file")
        with open(flatpakrunfile, "w") as frf:
            for line in FINAL:
                frf.write(line + "\n")

        time.sleep(2)
        save_conf_setting("FlatpakRunning", "true")
        log(
            "While the flatpak run file exists, the command still runns, so wait for the file to be removed"
        )
        while os.path.isfile(flatpakrunfile):
            flatrunn = load_conf_setting("FlatpakRunning")
            if (flatrunn and flatrunn == "new") or not flatrunn:
                log("New instance detected, closesing old instance")
                sys.exit(0)
            time.sleep(1)
        save_conf_setting("FlatpakRunning", None)

        log("Any errors from the runn command, get raised")
        if os.path.isfile(errorfile):
            with open(errorfile, "r") as fef:
                error = fef.read()
                os.remove(errorfile)
                if error:
                    raise Exception(str(error))

        log("Any warnings from the command the logged")
        if os.path.isfile(warnfile):
            with open(warnfile, "r") as fwf:
                warn = fwf.read()
                os.remove(warnfile)
                if warn:
                    log(
                        f"Problem loading the winesever waiter, the error is:\n\t{warn}"
                    )

        log("Finished flatpak mode code")
    else:
        log("Running in regular mode")
        save_conf_setting("FlatpakRunning", None)

        # Execute the final command
        process = subprocess.Popen(
            FINAL, stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )

        log("Communicating with the process")
        stdout, stderr = process.communicate()

        if stdout:
            log(stdout.decode("utf8"))

        if stderr:
            log(stderr.decode("utf8"))

        log("Process finished")
        resp = process.returncode

        if len(verb) == 0:
            log("Running the wineserver waiter")
            try:
                if os.path.isdir(os.path.join(WINEPREFIX, "drive_c")):
                    os.environ["WINEPREFIX"] = WINEPREFIX
                elif os.path.isdir(
                    os.path.join(BASE_STEAM_COMPAT, "drive_c")
                ):
                    os.environ["WINEPREFIX"] = BASE_STEAM_COMPAT
                else:
                    os.environ["WINEPREFIX"] = WINEPREFIX

                wserver = subprocess.run(
                    ["wineserver", "--wait"],
                    bufsize=1,
                    capture_output=True,
                    text=True,
                )
            except Exception as e:
                log(
                    f"Problem loading the winesever waiter, the error is:\n\t{e}"
                )
            else:
                print(str(wserver.stdout))
                print(str(wserver.stderr))

            log("Finished regular mode code")

    log("At this point the game should have allready finished running")
    if os.path.exists(ttfile):
        log("Deleteing early game tracking file")
        os.remove(ttfile)

    log("Waiting for early game tracking thread to finish")
    ttime_thread.join()

    troubleshooter()

    log(f"Exit command with {resp}")
    return "EXIT"


# Second main block
if __name__ == "__main__":
    # Main execution block
    RESP = ""
    logy = "No"
    try:
        RESP = run()
    except Exception as e:
        RESP = "ERR:\n" + str(e)
        logy = show_message(
            "Error occored, open the log?", "Error occored", 30, True
        )

    # Log final response or error
    log(str(RESP))
    log("\n\n\n")

    if not logy or logy == "Yes":
        log(open_log=True)
