#!/usr/bin/env python3
import os
import sys
from os import path
from sys import argv
import urllib
from subprocess import call, check_output
import shutil
import pathlib
from urllib import request
from urllib.request import urlretrieve
import lddwrap
import argparse
from resolve_library import resolve as resolve_library
basedir = path.realpath(path.dirname(__file__))
def download_always(url: str, filename: str) -> None:
    urlretrieve(url, filename)
def download_if_not_found(url: str, filename: str) -> None:
    if path.exists(filename):
        return
    download_always(url, filename)
def download_appimagetool():
    url = "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
    filename = "appimagetool"
    download_if_not_found(url, filename)
def build(*args: list[str]):
    call(args=["./build.sh", *args])
def remove_recursive(inpath: str):
    print("remove_recursive(%s)" % inpath)
    if path.isdir(inpath) and not path.islink(inpath):
        for inner in os.listdir(inpath):
            remove_recursive(path.join(inpath, inner))
        print("os.removedirs(%s)" % inpath)
        os.removedirs(inpath)
    elif path.islink(inpath):
        print("os.unlink(%s)" % inpath)
        os.unlink(inpath)
    else:
        print("os.remove(%s)" % inpath)
        os.remove(inpath)
def force_link(src: str, dst: str):
    if path.exists(dst):
        remove_recursive(dst)
    os.symlink(src, dst)
def force_copy(src: str, dst: str):
    print("force_copy(%s, %s)" % (src, dst))
    if path.exists(dst) and path.isdir(dst):
        dst = path.join(dst, path.basename(src))
    if path.exists(dst):
        remove_recursive(dst)
    shutil.copy(src, dst)
def copy_libraries(libpath: str, previous: list[str] = []):
    print("Getting libraries for '%s'..." % libpath)
    for lib in lddwrap.list_dependencies(pathlib.Path(libpath)):
        if str(lib.path) in previous:
            continue
        print(" - Library %s" % lib.soname, end="")
        if lib.path == None:
            print("")
            continue
        print(" (%s)" % lib.path)
        inpaths = resolve_library(str(lib.path))
        for inpath in inpaths:
            outpath = path.join("AppDir/lib", path.basename(inpath))
            force_copy(inpath, outpath)
        previous.append(str(lib.path))
        copy_libraries(str(lib.path), previous)
def overwrite_file(dst: str, contents: str):
    if path.exists(dst):
        remove_recursive(dst)
    with open(dst, "wt+") as f:
        f.write(contents)
def main() -> None:
    P = argparse.ArgumentParser()
    P.add_argument("-j", "--parallel", action=argparse._StoreAction, default=0, type=int, help="Specifies the number of jobs to use. Set to 1 to disable parallelism", dest="parallel")
    P.add_argument("-D", "--define", default=[], action=argparse._AppendAction, help="Defines a CMake variable", dest="cmake_vars")
    p = P.parse_args(argv[1:])
    old_dir = os.curdir
    os.chdir(basedir)
    os.chdir("build")
    args=["cmake", ".."]
    for definition in p.cmake_vars:
        args.append("-D%s" % definition)
    ret = call(args);
    if ret != 0:
        exit(ret)
    parallel = p.parallel
    if parallel == 0:
        parallel = os.cpu_count()
    args=["cmake", "--build", ".", "-j%d" % parallel]
    ret = call(args)
    if ret != 0:
        exit(ret)
    download_appimagetool()
    os.makedirs("AppDir", exist_ok=True)
    for dir in ["bin", "lib", "share"]:
        os.makedirs(path.join("AppDir", dir), exist_ok=True)
    force_link(".", "AppDir/usr")
    force_link(".", "AppDir/local")
    force_link("lib", "AppDir/lib64")
    force_copy("looper", "AppDir/bin")
    copy_libraries("looper")
    force_copy(path.join(basedir, "assets/com.complecwaft.Looper.desktop"), "AppDir")
    force_copy(path.join(basedir, "assets/icon.svg"), "AppDir/looper.svg")
    force_copy(path.join(basedir, "assets/icon.png"), "AppDir/looper.png")
    overwrite_file("AppDir/AppRun", """#!/bin/bash
export LD_LIBRARY_PATH="$APPDIR/lib"
if [ "$1" = "--gdb" ]; then
    shift
    exec gdb --args "$APPDIR/usr/bin/looper" "$@"
else
    exec "$APPDIR/usr/bin/looper" "$@"
fi""")
    os.chmod("AppDir/AppRun", 0o777)

    arch = check_output(["uname", "-m"])
    print("Architecture: %s" % arch.decode())
    os.environ["ARCH"] = arch.decode().removesuffix("\n")
    call(args=["./appimagetool", "AppDir", "Looper.AppImage"])
    os.chdir(old_dir)
if __name__ == "__main__":
    main()