#! /usr/bin/env python3

"""
This fast installer is destined to the developpers who want to create
their own quick installer, with 'geninstaller' (https://github.com/byoso/geninstaller).
Just read the comments and complete the informations asked below,
the magic will do the rest.

IMPORTANT:
Geninstaller only installs applications in the user's space, it does not
access to the system files. Therefore, each installation is relative
to one user of the computer. It is possible to install the application
on multiple sessions, but each application installed will remain totally
independent.

"""

# =========== THERE WE GO ===================================

# PLACE THIS FILE IN THE ROOT DIRECTORY OF YOUR PROJECT

# =====================================================================
# ======= Complete this informations ==================================

# choose a good name, do NOT use underscores here
NAME = "fake"
# short description (optional), a few words would be fine
DESCRIPTION = "A short description"
# The main executable file of the application
# The path is relative to this directory (BASE_DIR defined below)
EXECUTABLE = "fake/fake.py"
# The icon that your system will use (optional, but so much better)
# The path is relative to this directory (BASE_DIR defined below)
ICON = "fake/icon.png"
# Does your application needs to appear within a terminal ?
# (usually, a graphical application doesn't need a terminal)
TERMINAL = False

# Just uncomment the categories in which you want your app to appear in (optional).
# If you need to know more (expert), read this:
# freedesktop.org doc for categories
# https://specifications.freedesktop.org/menu-spec/latest/apa.html#main-category-registry
# additionnal categories
# https://specifications.freedesktop.org/menu-spec/latest/apas02.html
CATEGORIES = [
    # "AudioVideo",
    # "Audio",
    # "Video",
    # "Development",
    # "Education",
    # "Game",
    # "Graphics",
    # "Network",
    # "Office",
    # "Science",
    # "Settings",
    # "System",
    # "Utility",
]

# if your app needs python dependencies, list here the requirements files
# your program will be installed in a virtual environment with these dependencies
python_dependencies = []  # e.g. ["requirements.txt"]

# ADDITIONAL OPTIONS
exec_options = ""  # if the exec needs additional options

# if more parameters are needed in the .desktop file, fill this list
# with the lines you want. e.g: ["foo=bar", "truc=machin"]
options = [
    "Keywords=geninstaller;",
]

# optional pre installation/uninstallation script files (e.g. "scripts/pre_install.sh")
pre_install_script = ""
post_install_script = ""
pre_uninstall_script = ""

# you're done ! :)

# = do not touch what is following unless you know what you're doing ==
# =====================================================================


import os
import subprocess


# geninstaller version check
############################

# geninstaller_min_required_version = "1.0.0"  # dev
geninstaller_min_required_version = "2.1.0"  # prod

def version_from_string(v: str) -> tuple:
    return tuple(map(int, (v.split("."))))

def required_version(v1: str, min: str, max: str) -> bool:
    """Compares two version strings.
    Returns True if min <= v1 < max, else False."""
    current_version = version_from_string(v1)
    min_version = version_from_string(min)
    max_version = version_from_string(max)
    return current_version >= min_version and current_version < max_version

install_geninstaller_message = f"""
!! ABORTED !!
Geninstaller >= {geninstaller_min_required_version} must be installed with pipx before running this installer:
"""
install_geninstaller_message_pipx = f"""
# INSTALLING pipx:
Ubuntu / Debian             sudo apt install pipx ou pip install --user pipx
Fedora / RHEL / CentOS      sudo dnf install pipx
Arch / Manjaro              sudo pacman -S pipx
openSUSE                    sudo zypper install pipx
"""
install_geninstaller_messge_geninstaller = f"""
# INSTALLING geninstaller with pipx:
$ pipx install geninstaller
"""

try:
    installed_pipx = subprocess.run(
        ["pipx", "list", "--short"],
        capture_output=True,
        text=True,
        check=False
    )
except FileNotFoundError:
    message = install_geninstaller_message + install_geninstaller_message_pipx + install_geninstaller_messge_geninstaller
    print(message)
    exit(0)
installed_list = installed_pipx.stdout.strip().splitlines()
installed_tools = {i: j for i, j in (item.split() for item in installed_list)}

# this check only works with python 3.12 and above due to pipx issues with older versions
import sys
MIN_PYTHON = (3, 12)
if sys.version_info >= MIN_PYTHON:
    if not "geninstaller" in installed_tools or not required_version(installed_tools["geninstaller"], geninstaller_min_required_version, "3.0.0"):
        message = install_geninstaller_message + install_geninstaller_messge_geninstaller
        print(message)
        exit(0)
else:
    print(f"WARNING: Your version of python is {sys.version_info.major}.{sys.version_info.minor}, to ancient to run some pipx verifications, install continues anyway...")


# Installation with geninstaller
################################

this_file = os.path.basename(__file__)


BASE_DIR = os.path.abspath(os.path.dirname(__file__))

def install() -> None:
    """installs the application with geninstaller"""
    # building the query parameters
    options_formated = [opt.replace("=", "<eq>") for opt in options]  # avoid issues with bash
    query_params = f'?name="{NAME}"+exec="{EXECUTABLE}"+description="{DESCRIPTION}"+' \
        f'terminal="{TERMINAL}"+icon="{ICON}"+categories="{";".join(CATEGORIES)}"+' \
        f'base_dir="{BASE_DIR}"+exec_options="{exec_options}"+options="{";".join(options_formated)}"+' \
        f'pre_install_script="{pre_install_script}"+post_install_script="{post_install_script}"+' \
        f'pre_uninstall_script="{pre_uninstall_script}+' \
        f'python_dependencies="{";".join(python_dependencies)}"'
    try:
        subprocess.run(
            ["geninstaller", "_install", query_params],  # prod
            # ["python", "-m", "geninstaller.cmd", "_install", query_params],  # dev
            check=True
        )
    except Exception as e:
        print(f"Installation failed: {e}")
        exit(1)

def main() -> None:
    install()


if __name__ == "__main__":
    main()
