#!/bin/sh

CMAKE=cmake
ENABLE_FFMPEG=1

main() {
    cd "$(dirname $0)"

    check_command_line_args "$@"

    mktmp

    check_os

    ${os}_installdeps

    quit 0
}

check_command_line_args() {
    while [ $# -gt 0 ]; do
        case "$1" in
            -h|--help|--usage)
                usage
                quit 0
                ;;
            --no-ffmpeg)
                ENABLE_FFMPEG=
                shift
                ;;
            *)
                target=$1
                break
                ;;
        esac
    done

    if [ $# -gt 1 ]; then
        usage
        quit 1
    fi
}

check_os() {
    case "$(uname -s)" in
        Linux)
            os=linux
            ;;
        Darwin)
            os=mac
            ;;
        FreeBSD)
            os=freebsd
            ;;
        MINGW*|MSYS*)
            os=windows
            ;;
        *)
            error "Don't know how to install deps on your OS"
            ;;
    esac
}

mktmp() {
    tmp="/tmp/installdeps_$$"
    mkdir "$tmp" || quit 1
    chmod 700 "$tmp" 2>/dev/null
    trap "quit 1" PIPE HUP INT QUIT ILL TRAP KILL BUS TERM
}

quit() {
    [ -n "$tmp" ] && rm -rf "$tmp" 2>/dev/null
    exit ${1:-0}
}

usage() {
    cat <<'EOF'
Usage: [32m./installdeps [1;35m[TARGET][0m

Try to install the dependencies needed for this project appropriately on the host OS.

This program may require [1;35msudo[0m.

A cross-compile target may be specified as the only parameter, of either [1;35mm32[0m which targets the host in 32 bit mode (e.g. x86 on an amd64 host) or [1;35mwin32[0m, [1;35mMinGW-w64-i686[0m or [1;35mMinGW-w64-x86_64[0m.  [1;35mwin32[0m is an alias for [1;35mMinGW-w64-i686[0m to target Windows via MinGW.  Cross compiling for Windows is only supported on Debian/Ubuntu, Fedora, Arch Linux and MSYS2.

On MSYS2 the [1;35mMinGW-w64-clang-x86_64[0m target for CLANG64 and the [1;35mMinGW-w64-clang-i686[0m target for CLANG32 are also supported, as well as [1;35mMinGW-w64-ucrt-x86_64[0m for UCRT64.

On MSYS2 dependencies are installed for 32 or 64 bit native Windows targets based on which shell you started (the value of $MSYSTEM) unless you specify one or the other. You can specify a cross target of [1;35mm32[0m or [1;35mm64[0m as aliases for the 32 bit or 64 bit MinGW gcc targets respectively. MSYS2 POSIX layer builds are not supported.

  [1m-h, --help, --usage[0m                Show this help screen and exit.
  [1m--no-openal[0m                        Do not install OpenAL dependencies.
  [1m--no-ffmpeg[0m                        Do not install ffmpeg dependencies.

Examples:
  [32m./installdeps[0m                        # install dependencies for a host build
  [32m./installdeps [1;35mm32[0m                    # make a 32 bit binary for the host OS
  [32m./installdeps [1;35mwin32[0m                  # cross-compile for 32 bit windows (Debian/Ubuntu, Arch Linux or MSYS2)
  [32m./installdeps [1;35mMinGW-w64-i686[0m         # likewise
  [32m./installdeps [1;35mwin64[0m                  # cross-compile for 64 bit windows (Debian/Ubuntu, Arch Linux or MSYS2)
  [32m./installdeps [1;35mMinGW-w64-x86_64[0m       # likewise
EOF
}

error() {
    printf '\n[31mERROR[0m: %s.\n\n' "$1" >&2
    [ -z "$2" ] && quit 1
}

warning() {
    [ -z "$1" ] && return 0
    printf '\n[35mWARNING[0m: %s.\n\n' "$1" >&2
}


info_msg() {
    [ -z "$1" ] && return 0
    printf '\n[32mINFO[0m: %s.\n\n' "$1" >&2
}

installing() {
    echo '[32mInstalling deps...[0m'
    echo
}

check() {
    "$@"
    if [ $? -ne 0 ]; then
        error 'command failed' NOQUIT
        echo 'The failing command was:'
        echo "$@"
        quit 1
    fi
}

countdown() {
    secs=$1
    echo
    while [ "$secs" -ne 0 ]; do
        printf '%s\r' "Starting in $secs seconds..."
        sleep 1
        secs=$((secs-1))
    done
    printf '\n\n'
}

linux_installdeps() {
    # detect host architecture
    case "$(uname -a)" in
        *x86_64*)
            amd64=1
            ;;
        *i686*)
            i686=1
            ;;
    esac

    if [ -f /etc/debian_version ]; then
        debian_installdeps
    elif [ -f /etc/fedora-release ]; then
        fedora_installdeps
    elif [ -f /etc/redhat-release ] || [ -f /etc/centos-release ]; then
        rhel_installdeps
    elif [ -f /etc/solus-release ]; then
        solus_installdeps
    elif [ -f /etc/gentoo-release ]; then
        gentoo_installdeps
    elif [ -x /usr/bin/pacman ]; then
        archlinux_installdeps
    elif [ -f /etc/os-release ]; then
        case "$(. /etc/os-release; echo "${ID_LIKE:-$ID}")" in
            *suse*)
                suse_installdeps
                ;;
            nixos)
                nixos_installdeps
                ;;
            alpine)
                alpine_installdeps
                ;;
            *)
                error "Don't know how to install deps on your version of Linux"
                ;;
        esac
    else
        error "Don't know how to install deps on your version of Linux"
    fi
}

freebsd_installdeps() {
    installing

    check sudo pkg update

    pkgs="llvm-devel cmake ccache nasm ffmpeg gettext-tools gettext pkgconf sdl3 wx31-gtk3 iconv zip ninja"

    [ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs ffmpeg"

    # currently the wx30 and wx31 packages produce GTK errors on CURRENT (as of 04/2019)
    check sudo pkg install -y $pkgs

    build_instructions
}

# the -j flag for make parameter, empty if 1
jobs_flag() {
    if [ $(num_cpus) -gt 1 ]; then
        echo "-j$(num_cpus)"
    fi
}

# number of CPUs to use for jobs, 1 less than total to not overload resources
num_cpus() {
    if [ -n "$_num_cpus" ]; then
        if [ $((_num_cpus - 1)) -lt 1 ]; then
            echo 1
        else
            echo $((_num_cpus - 1))
        fi
        return 0
    fi

    # determine number of CPUs and cache it
    if command -v nproc >/dev/null; then
        _num_cpus=$(nproc)
    elif [ $os = linux -o $os = windows ]; then
        _num_cpus=$(grep '^processor		*:' /proc/cpuinfo | wc -l)
    elif [ $os = mac ] || [ $os = freebsd ]; then
        _num_cpus=$(sysctl -n hw.ncpu)
    fi

    [ -z "$_num_cpus" ] && _num_cpus=1

    num_cpus
}

check_cross() {
    target=$(echo "$target" | tr 'A-Z' 'a-z')

    if [ -z "$target" ]; then
        if [ -n "$msys2" ]; then
            case "$MSYSTEM" in
                MINGW32)
                    target='mingw-w64-i686'
                    ;;
                MINGW64)
                    target='mingw-w64-x86_64'
                    ;;
                CLANG32)
                    target='mingw-w64-clang-i686'
                    ;;
                CLANG64)
                    target='mingw-w64-clang-x86_64'
                    ;;
                UCRT64)
                    target='mingw-w64-ucrt-x86_64'
                    ;;
                MSYS)
                    error 'host builds in MSYS mode are not supported, supply a target or start a MINGW shell'
                    ;;
                *)
                    error 'unknown value for $MSYSTEM: '"$MSYSTEM"' '
                    ;;
            esac
        else
            return
        fi
    fi

    case "$target" in
        win32|win64|mingw*)
            if [ -z "$arch_linux" -a -z "$msys2" -a -z "$debian" -a -z "$fedora" ]; then
                error 'win32 cross compiling targets are only supported on Debian/Ubuntu, Fedora, Arch and MSYS2 at the moment'
            fi

            case "$target" in
                win32)
                    target='mingw-w64-i686'
                    ;;
                win64)
                    target='mingw-w64-x86_64'
                    ;;
                mingw-w64-x86_64|mingw-w64-i686|mingw-w64-clang-x86_64|mingw-w64-ucrt-x86_64|mingw-w64-clang-i686)
                    ;;
                *)
                    error "target must be one of 'm32', 'win32', 'win64', or one of the MinGW/clang/ucrt targets supported by MSYS2: mingw-w64-[clang|ucrt]-(x86_64|i686)."
                    ;;
            esac
            ;;
        m32|-m32)
            target=m32
            if [ -z "$msys2" -a -z "$fedora" -a -z "$arch_linux" -a -z "$solus" -a -z "$suse" ]; then
                error '32 bit builds are only supported on Fedora, OpenSUSE, Arch, Solus and MSYS2 at the moment'
            fi

            if [ -n "$msys2" ]; then
                target='mingw-w64-i686'
            else
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake"
            fi
            ;;
        m64)
            if [ -z "$msys2" ]; then
                error '64 bit cross target only supported on MSYS2 at the moment'
            fi
            target='mingw-w64-x86_64'
            ;;
        *)
            error "unknown cross target: '$target' "
            ;;
    esac
}

debian_installdeps() {
    debian=1
    check_cross
    installing

    if [ -z "$target" ]; then
        sudo apt-get -qq -y update

        glew_lib=$(apt-cache search libglew | grep '^libglew[0-9]' | sed 's/ - .*//' | sort -r | head -1)

        # not present in trusty
        if [ -n "$ENABLE_FFMPEG" ]; then
            libswresample_dev=$(apt-cache search libswresample-dev | awk '{print $1}')
        fi

        wx_libs=$(apt-cache search 'libwxgtk[0-9]' | sed 's/ - .*//')

        # Use -gtk3 variant on older distros.
        case "$wx_libs" in
            *-gtk3*)
                new_wx_libs=
                for pkg in $wx_libs; do
                    case "$pkg" in
                        *-gtk3*)
                            new_wx_libs="$new_wx_libs $pkg"
                            ;;
                    esac
                done
                wx_libs=$new_wx_libs
                ;;
        esac

        sdl_lib=$(apt-cache search libsdl3-dev | grep libsdl3-dev | awk '{ print $1 }')
        [ -z "$sdl_lib" ] && sdl_lib=libsdl2-dev

        pkgs="build-essential g++ nasm cmake ccache gettext zlib1g-dev libgl1-mesa-dev libgettextpo-dev $sdl_lib libglu1-mesa-dev libglu1-mesa libgles2-mesa-dev $glew_lib $wx_libs libgtk2.0-dev libgtk-3-dev ccache zip ninja-build libopenal-dev"

        [ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs libavcodec-dev libavformat-dev libswscale-dev libavutil-dev $libswresample_dev libx264-dev libx265-dev"

        check sudo apt-get -qy install $pkgs
    else
        case "$target" in
            mingw-w64-i686)
                target='i686-w64-mingw32.static'
                CMAKE="/usr/lib/mxe/usr/bin/i686-w64-mingw32.static-cmake"
                ;;
            mingw-w64-x86_64)
                target='x86-64-w64-mingw32.static'
                CMAKE="/usr/lib/mxe/usr/bin/x86_64-w64-mingw32.static-cmake"
                ;;
            *)
                error "unknown cross target (you shouldn't see this)"
                ;;
        esac

        pre_build='export PATH="$PATH:/usr/lib/mxe/usr/bin"'

        debian_rel=$(lsb_release -a 2>/dev/null | sed -En 's/^Codename:[[:space:]]*//p')

        case "$debian_rel" in
            bionic|stretch|trusty|xenial)
                ;;
            yakkety|zesty|artful)
                debian_rel=xenial
                ;;
            utopic|vivid|wily)
                debian_rel=trusty
                ;;
            *)
                debian_rel=bionic
                ;;
        esac

        mxe_apt_sources=/etc/apt/sources.list.d/mxeapt.list

        sudo apt-get -qq -y update

        if [ -z "$(apt-cache search '^mxe-source$')" ]; then
            if [ ! -f "$mxe_apt_sources" ]; then
                echo "deb http://pkg.mxe.cc/repos/apt $debian_rel main" | sudo -- sh -c "cat > $mxe_apt_sources"
                sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C6BF758A33A3A276 || :
            else
                error "$mxe_apt_sources exists but mxe packages are not found in apt, either delete it or fix it"
            fi
        fi

        deps="gcc zlib ffmpeg gettext sdl3 openal wxwidgets openal"
        [ -n "$ENABLE_FFMPEG" ] && deps="$deps ffmpeg"

        set --
        for dep in $deps; do
            set -- "$@" "mxe-${target}-$dep"
        done
        check sudo apt-get --allow-unauthenticated -qq -y update

        # Native wx-common needed for wxrc executable.
        check sudo apt-get --allow-unauthenticated -qy install build-essential cmake ninja-build ccache wx-common git "$@"

        # The ccache symlink is broken in some versions of these mxe packages.
        ccache_link=/usr/lib/mxe/.ccache/bin/ccache

        if [ ! -e "$ccache_link" ]; then
            sudo mkdir -p ${ccache_link%/*}
            sudo ln -sf /usr/bin/ccache "$ccache_link"
        fi

        # get the necessary win32 headers
        git submodule update --init --remote --recursive
    fi

    build_instructions
}

fedora_installdeps() {
    fedora=1
    ffmpeg=ffmpeg-devel
    rpms_installed=

    check_cross
    installing

    warning=

    if [ -n "$ENABLE_FFMPEG" ]; then
        # using --nogpgcheck with dnf because keys can be a problem on rawhide

        fedora_release=$(rpm -E %fedora)
        tries=3
        curdir=$(pwd)

        # make sure rpmfusion is installed for ffmpeg
        while [ $tries -gt 0 ]; do
            mkdir -p "${tmp}/fusion"
            cd "${tmp}/fusion"
            if ! curl -fLO https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-${fedora_release}.noarch.rpm; then
                fedora_release=$((fedora_release - 1))
                tries=$((tries - 1))
                continue
            fi
            if ! curl -fLO https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-${fedora_release}.noarch.rpm; then
                tries=0
                break
            fi
            # check if already installed
            if rpm -q rpmfusion-free-release-${fedora_release} >/dev/null 2>&1 && rpm -q rpmfusion-nonfree-release-${fedora_release} >/dev/null 2>&1; then
                info_msg 'rpmfusion already installed, good'
                break
            fi
            # otherwise try to install
            if ! sudo rpm --nodeps -Uvh ./rpmfusion-*.rpm; then
                tries=0
                break
            fi
            break
        done
        cd "$curdir"
        if [ $tries -eq 0 ]; then
            warning 'installing rpmfusion repos failed, continuing without ffmpeg'
            no_ffmpeg=1
        fi
    fi

    # non-multiarch packages first
    check sudo dnf -y --nogpgcheck --best --allowerasing install gcc gcc-c++ make cmake ccache git nasm redhat-rpm-config pkgconfig ccache ninja-build

    # try to install multiarch libgcc, glibc-devel and pkgconfig if available
    if [ -n "$amd64" ]; then
        for pkg in pkgconfig libgcc glibc-devel; do
            if [ "$target" = m32 ]; then
                sudo dnf -y --nogpgcheck --best --allowerasing install "$pkg".i686
            else
                sudo dnf -y --nogpgcheck --best --allowerasing install "$pkg".x86_64
            fi
        done
    fi

    set --
    if [ -z "$target" -o "$target" = m32 ]; then
        # try to install both 64 bit and 32 bit versions on 64 bit hosts (see below)
        if [ -n "$amd64" ]; then
            # this is sometimes necessary for rawhide
            set -- --exclude='glibc32*'
        fi
        for pkg in zlib-devel mesa-libGL-devel ffmpeg-devel gettext-devel SDL3-devel openal-soft-devel wxGTK-devel gtk3-devel; do
            case $pkg in
                *ffmpeg*)
                    [ -z "$ENABLE_FFMPEG" ] && continue
                    ;;
            esac

            pkg_arch=
            if [ -n "$amd64" ]; then
                pkg_arch=.x86_64

                if [ "$target" = m32 ]; then
                    pkg_arch=.i686
                fi
            fi

            # Check which is newer, wxGTK or wxGTK3.
            if [ "$pkg" = wxGTK-devel ]; then
                pkg=$(dnf -q --releasever=$(rpm -E %fedora) --showduplicates list wxGTK-devel wxGTK3-devel 2>/dev/null | awk '{ print $1 "\t" $2 }' | grep -Ev '^(Installed|Available)' | sort -rVu -k 2,2 | head -1 | awk '{ print $1 }' | sed -E 's/\.[^.]+//')

                [ -z "$pkg" ] && pkg=wxGTK3-devel
            fi

            set -- "$@" "${pkg}${pkg_arch}"
        done

        # fedora has a bug where all necessary -devel packages are not pulled in for 32 bit direct -devel deps
        # this hack adds them to the list
        if [ -n "$amd64" -a "$target" = m32 ]; then
            info_msg 'Calculating dependencies, this will take a while..'
            curdeps=
            newdeps=$@
            while [ "$curdeps" != "$newdeps" ]; do
                curdeps=$newdeps
                set -- $(echo "$@" $(sudo dnf -y --nogpgcheck repoquery --deplist "$@" 2>/dev/null | sed -n 's/\.x86_64$/.i686/; s/^ *provider: *\([^ ]*-devel-.*\)$/\1/p' | sort -u) | sed 's/  */\n/g' | sort -u)
                newdeps=$@
                printf '%s' .
            done

            echo
            info_msg 'Done'

            ## install the RPMs with rpm --force get around file conflicts

            host_rpms=$(echo "$@" | sed 's/\.i686//g')

            # first update the host arch versions to reduce chances of conflicts
            check sudo dnf -y --nogpgcheck --allowerasing --best install $host_rpms

            oldcwd=$PWD
            mkdir "$tmp/rpms"
            cd "$tmp/rpms"

            check sudo dnf -y --nogpgcheck --allowerasing --best download "$@"

            # first try installing with dnf to pull in deps
            check sudo dnf -y --nogpgcheck --allowerasing --best --skip-broken install *.rpm

            # follow up with rpm --force to ignore conflicts
            check sudo rpm -Uvh --force *.rpm

            rm -f *.rpm

            # reinstall the host rpms to make sure any overwritten files are the host version
            check sudo dnf -y --nogpgcheck --allowerasing --best download $host_rpms

            check sudo dnf -y --nogpgcheck --allowerasing --best --skip-broken install *.rpm

            check sudo rpm -Uvh --force *.rpm

            cd "$oldcwd"
            rm -rf "$tmp/rpms"

            ffmpeg=ffmpeg-devel.i686

            rpms_installed=1
        fi
    else # mingw build
        set -- "$@" pkgconfig
        case "$target" in
            mingw-w64-i686)
                target=mingw32
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-i686-static.cmake"
                ;;
            mingw-w64-x86_64)
                target=mingw64
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-x86_64-static.cmake"
                ;;
            *)
                error 'unknown cross target (this should not happen)'
                ;;
        esac
        # install static deps
        for pkg in zlib gettext SDL3 wxWidgets3 openal-soft; do
            set -- "$@" "${target}-${pkg}-static"
        done

        # get the necessary win32 headers
        git submodule update --init --remote --recursive
    fi

    [ -z "$rpms_installed" ] && check sudo dnf -y --nogpgcheck --best --allowerasing install "$@"

    if [ -n "$ENABLE_FFMPEG" ] && ! rpm -q $ffmpeg >/dev/null 2>&1; then
        warning 'ffmpeg failed to install (probably due to conflicts)'
    fi

    [ -n "$warning" ] && warning "$warning"

    build_instructions
}

rhel_installdeps() {
    rhel=1
    ffmpeg=ffmpeg-devel
    rpms_installed=

    check_cross
    installing

    warning=

    rhel_release=$(rpm -E %rhel)
    tries=3
    curdir=$(pwd)

    # this source is necessary for mingw packages on rhel, and may be for other things in the future
    check sudo yum -y install epel-release

    # make sure rpmfusion is installed for ffmpeg
    if [ -n "$ENABLE_FFMPEG" ]; then
        while [ $tries -gt 0 ]; do
            mkdir -p "${tmp}/fusion"
            cd "${tmp}/fusion"
            if ! curl -fLO https://download1.rpmfusion.org/free/el/rpmfusion-free-release-${rhel_release}.noarch.rpm; then
                rhel_release=$((rhel_release - 1))
                tries=$((tries - 1))
                continue
            fi
            if ! curl -fLO https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-${rhel_release}.noarch.rpm; then
                tries=0
                break
            fi
            # check if already installed
            if rpm -q rpmfusion-free-release-${rhel_release} >/dev/null 2>&1 && rpm -q rpmfusion-nonfree-release-${rhel_release} >/dev/null 2>&1; then
                info_msg 'rpmfusion already installed, good'
                break
            fi
            # otherwise try to install
            if ! sudo rpm --nodeps -Uvh ./rpmfusion-*.rpm; then
                tries=0
                break
            fi
            break
        done
        cd "$curdir"
        if [ $tries -eq 0 ]; then
            warning 'installing rpmfusion repos failed, continuing without ffmpeg'
        fi
    fi

    # non-multiarch packages first
    CMAKE=cmake3
    check sudo yum -y install gcc gcc-c++ make cmake3 ccache git nasm redhat-rpm-config pkgconfig ccache ninja-build

    # try to install multiarch libgcc, glibc-devel and pkgconfig if available
    if [ -n "$amd64" ]; then
        for pkg in pkgconfig libgcc glibc-devel; do
            if [ "$target" = m32 ]; then
                sudo yum -y install "$pkg".i686
            else
                sudo yum -y install "$pkg".x86_64
            fi
        done
    fi

    set --
    if [ -z "$target" -o "$target" = m32 ]; then
        # try to install both 64 bit and 32 bit versions on 64 bit hosts (see below)
        if [ -n "$amd64" ]; then
            # this is sometimes necessary for rawhide
            set -- --exclude='glibc32*'
        fi

        for pkg in zlib-devel mesa-libGL-devel ffmpeg-devel gettext-devel SDL3-devel openal-soft-devel wxGTK3-devel gtk3-devel; do
            case $pkg in
                *ffmpeg*)
                    [ -z "$ENABLE_FFMPEG" ] && continue
                    ;;
            esac

            if [ -n "$amd64" ]; then
                if [ "$target" = m32 ]; then
                    set -- "$@" "${pkg}.i686"
                else
                    set -- "$@" "${pkg}.x86_64"
                fi
            else
                set -- "$@" "$pkg"
            fi
        done

        # redhat has a bug where all necessary -devel packages are not pulled in for 32 bit direct -devel deps
        # this hack adds them to the list
        if [ -n "$amd64" -a "$target" = m32 ]; then
            info_msg 'Calculating dependencies, this will take a while..'
            curdeps=
            newdeps=$@
            while [ "$curdeps" != "$newdeps" ]; do
                curdeps=$newdeps
                set -- $(echo "$@" $(repoquery --deplist "$@" 2>/dev/null | sed -n 's/\.x86_64$/.i686/; s/^ *provider: *\([^ ]*-devel-.*\)$/\1/p' | sort -u) | sed 's/  */\n/g' | sort -u)
                newdeps=$@
                printf '%s' .
            done

            echo
            info_msg 'Done'

            ## install the RPMs with rpm --force get around file conflicts

            host_rpms=$(echo "$@" | sed 's/\.i686//g')

            # first update the host arch versions to reduce chances of conflicts
            check sudo yum -y install $host_rpms

            oldcwd=$PWD
            mkdir "$tmp/rpms"
            cd "$tmp/rpms"

            check sudo yum -y download "$@"

            # first try installing with yum to pull in deps
            check sudo yum -y --skip-broken install *.rpm

            # follow up with rpm --force to ignore conflicts
            check sudo rpm -Uvh --force *.rpm

            rm -f *.rpm

            # reinstall the host rpms to make sure any overwritten files are the host version
            check sudo yum -y download $host_rpms

            check sudo yum -y --skip-broken install *.rpm

            check sudo rpm -Uvh --force *.rpm

            cd "$oldcwd"
            rm -rf "$tmp/rpms"

            ffmpeg=ffmpeg-devel.i686

            rpms_installed=1
        fi
    else # mingw build
        set -- "$@" pkgconfig
        case "$target" in
            mingw-w64-i686)
                target=mingw32
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-i686.cmake"
                ;;
            mingw-w64-x86_64)
                target=mingw64
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-x86_64.cmake"
                ;;
            *)
                error 'unknown cross target (this should not happen)'
                ;;
        esac
        # install static deps
        for pkg in zlib gettext SDL3 wxWidgets openal-soft; do
            set -- "$@" "${target}-${pkg}-static"
        done

        # get the necessary win32 headers
        git submodule update --init --remote --recursive
    fi

    [ -z "$rpms_installed" ] && check sudo yum -y install "$@"

    if [ -n "$ENABLE_FFMPEG" ] && ! rpm -q $ffmpeg >/dev/null 2>&1; then
        warning 'ffmpeg failed to install (probably due to conflicts)'
    fi

    [ -n "$warning" ] && warning "$warning"

    build_instructions
}

suse_installdeps() {
    suse=1
    check_cross
    installing

    tools="make cmake ccache nasm gettext-tools pkg-config ccache zip ninja"

    libs="gcc gcc-c++ SDL3-devel wxGTK3-3_2-devel openal-soft-devel ffmpeg-7-libavcodec-devel ffmpeg-7-libavdevice-devel ffmpeg-7-libavfilter-devel ffmpeg-7-libavformat-devel ffmpeg-7-libavutil-devel ffmpeg-7-libpostproc-devel ffmpeg-7-libswresample-devel ffmpeg-7-libswscale-devel"

    if [ "$target" = m32 ]; then
        error '32 bit cross builds are no longer supported on OpenSUSE'
    fi

    check sudo zypper in -y $tools $libs

    build_instructions
}

nixos_installdeps() {
    nixos=1

    cat <<EOF

[32mTo build run:[0m

nix-shell --command 'mkdir build; cd build; $CMAKE .. $cmake_flags -G Ninja; ninja'

EOF
}

archlinux_require_yaourt() {
    if ! command -v yaourt >/dev/null; then
        (
            cd "$tmp"
            git clone https://aur.archlinux.org/package-query.git
            cd package-query
            makepkg --noconfirm -si
            cd ..
            git clone https://aur.archlinux.org/yaourt.git
            cd yaourt
            makepkg --noconfirm -si
        )
        [ $? -ne 0 ] && error 'could not install yaourt'
    fi
    pacman='yaourt --aur --m-arg=--skipinteg'
}

archlinux_installdeps() {
    arch_linux=1

    pacman='sudo pacman'
    command -v pacaur >/dev/null && pacman='pacaur --noedit'
    command -v yaourt >/dev/null && pacman='yaourt --aur --m-arg=--skipinteg'

    check_cross
    installing

    # check for gcc-multilib
    gcc_pkg=gcc
    if $pacman -Q gcc-multilib >/dev/null 2>&1; then
        gcc_pkg=gcc-multilib
    fi

    # update catalogs
    check $pacman -Sy

    # common needed dev packages
    # not using the base-devel group because it can break gcc-multilib
    check $pacman --noconfirm --needed -S binutils file grep gawk gzip libtool make patch sed util-linux nasm cmake ccache pkg-config git ccache zip ninja

    gtk=gtk3

    $pacman -Q gtk3-classic >/dev/null 2>&1 && gtk=gtk3-classic

    libs="zlib mesa gettext sdl3 wxgtk3 $gtk openal"

    [ -n "$ENABLE_FFMPEG" ] && libs="$libs ffmpeg"

    if [ -z "$target" -o "$target" = m32 ]; then
        if [ -z "$target" -o -z "$amd64" ]; then
            # Native build.
            #
            # On newer versions wxgtk2 may have to be manually removed.
            if ! $pacman --noconfirm --needed -S "$gcc_pkg" $libs; then
                $pacman --noconfirm -R wxgtk2
            fi
            $pacman --noconfirm --needed -S "$gcc_pkg" $libs
        else
            # try to build 32 bit binaries

            # lib32-ffmpeg is in AUR
            archlinux_require_yaourt

            # enable multilib repos if not enabled
            cp /etc/pacman.conf ${tmp}/pacman.conf
            cat <<'EOF' >> ${tmp}/pacman.conf
[multilib-testing]
Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
EOF
            pacman="$pacman --config ${tmp}/pacman.conf"

            # pull in multilib repo info
            $pacman -Sy

            yes | check $pacman --needed -S gcc-multilib

            libs32=
            for lib in $libs; do
                libs32="$libs32 lib32-$lib"
            done

            check $pacman --noconfirm --needed -S $libs32
        fi
    else
        # windows cross build
        case "$target" in
            *i686*)
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-i686.cmake"
                ;;
            *x86_64*)
                cmake_flags="$cmake_flags -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-MinGW-w64-x86_64.cmake"
                ;;
            *)
                # this will never be reached, it's checked in check_cross()
                error 'unknown cross target (you should not see this)'
                ;;
        esac

        check $pacman --noconfirm --needed -S "$gcc_pkg"

        archlinux_require_yaourt

        pkg_prefix='mingw-w64-'

        # cross toolchain (without headers and crt, we'll use -git versions)
        set --
        for p in binutils gcc winpthreads; do
            set -- "$@" "${pkg_prefix}${p}"
        done
        check $pacman --noconfirm --needed -S "$@"

        # build library deps from AUR

        info_msg 'We will now build dependencies from AUR, this will take quite a while and has a high probability of failure. In fact, it is definitely broken at the time of this writing. Press CTRL-C now to abort'

        countdown 16

        # pass appropriate make -jX flag through makepkg
        export MAKEPKG_CONF=${MAKEPKG_CONF:-/etc/makepkg.conf}

        grep -Ev '^[ 	]*MAKEFLAGS=' "$MAKEPKG_CONF" > "$tmp/makepkg.conf"

        export MAKEFLAGS=$(jobs_flag)
        echo "MAKEFLAGS=\"$MAKEFLAGS\"" >> "$tmp/makepkg.conf"

        export MAKEPKG_CONF="$tmp/makepkg.conf"

        # now do the AUR builds

        # first we need -headers-git and -crt-git (unless the non-git packages are installed)
        for p in "${pkg_prefix}headers" "${pkg_prefix}crt"; do
          if ! $pacman -Q "$p" >/dev/null 2>&1; then
              check $pacman --noconfirm --needed -S "${p}-git"
          else
              warning "${pkg_prefix}headers-git and ${pkg_prefix}crt-git are recommended over the regular versions, if you have build failures try to install them"
          fi
        done

        deps="zlib gettext pkg-config sdl3 wxmsw openal"

        # and the actual deps
        for p in $deps; do
            pkg="${pkg_prefix}${p}"
            # check if already installed
            if ! $pacman -Q "$pkg" >/dev/null 2>&1; then
                set -- "$@" "${pkg_prefix}${p}"
            fi
        done
        [ $# -gt 0 ] && check $pacman --noconfirm --needed -S "$@"

        # get the necessary win32 headers
        git submodule update --init --remote --recursive
    fi

    build_instructions
}

solus_installdeps() {
    solus=1

    check_cross
    installing

    check sudo eopkg -y update-repo
    check sudo eopkg -y install -c system.devel
    check sudo eopkg -y install git ccache ninja

    set -- sdl3-devel wxwidgets-devel libgtk-2-devel libgtk-3-devel libglu-devel openal-soft-devel

    if [ -n "$amd64" -a "$target" = m32 ]; then
        info_msg 'Calculating dependencies, this will take a while..'

        # first expand all dep lists recursively for -devel packages
        curdeps=
        newdeps=$@
        while [ "$curdeps" != "$newdeps" ]; do
            curdeps=$newdeps
            set -- $(echo "$@" $(sudo eopkg info "$@" 2>/dev/null | sed -n 's/^Dependencies  *:  *\(.*\)/\1/p' | sort -u) | sed 's/  */\n/g' | grep -- '-devel$' | sort -u)
            newdeps=$@
        done

        # transform to 32bit package names
        first=1
        for pkg in "$@"; do
            if [ "$first" = 1 ]; then
                set --
                first=0
            fi
            case "$pkg" in
                *-32bit-devel)
                    # already 32 bit
                    ;;
                *-devel)
                    set -- "$@" "${pkg%-devel}-32bit-devel"
                    ;;
                *)
                    set -- "$@" "$pkg"
                    ;;
            esac
        done

        # prune the ones that don't exist
        first=1
        for pkg in "$@"; do
            if [ "$first" = 1 ]; then
                set --
                first=0
            fi
            if ! sudo eopkg info "$pkg" | grep -q 'not found in binary repositories'; then
                set -- "$@" "$pkg"
            fi
        done
    else
        # no 32bit versions of these
        set -- "$@" ffmpeg-devel
    fi

    check sudo eopkg -y install "$@"

    if [ -n "$amd64" -a "$target" = m32 ]; then
        warning 'ffmpeg is required for game recording, there is no 32 bit ffmpeg package in Solus currently, you may wish to install it manually'
    fi

    build_instructions
}

gentoo_installdeps() {
    installing

    check sudo emerge-webrsync

    # We want the gtk3 slot for wxWidgets.
    wx_slot=$(equery -qC list -p -F '$slot' x11-libs/wxGTK | grep gtk3 | sort -rV | head -1)

    ebuilds="\
      sys-devel/gcc \
      dev-build/make \
      dev-build/cmake \
      dev-util/ccache \
      sys-devel/binutils \
      media-libs/libsdl3 \
      media-libs/openal \
      x11-libs/wxGTK:$wx_slot \
      sys-libs/zlib \
      dev-util/pkgconf \
      dev-lang/nasm \
      dev-build/ninja"

    [ -n "$ENABLE_FFMPEG" ] && ebuilds="$ebuilds media-video/ffmpeg"

    check sudo emerge -vna $ebuilds

    build_instructions
}

alpine_installdeps() {
    installing

    check sudo apk add cmake ninja g++ ccache nasm gettext-dev zlib-dev mesa-dev sdl3-dev glu-dev wxwidgets-dev gtk+3.0-dev zip

    build_instructions
}


windows_installdeps() {
    msys2=1

    check_cross
    installing

    # update catalogs
    check pacman -Sy

    pkgs=

    case "$target" in
        *clang*)
            pkgs="lldb clang"
            ;;
        *)
            pkgs="gcc gcc-libs gcc-libgfortran"
            ;;
    esac

    case "$target" in
        *i686*)
            pkgs="$pkgs nasm"
            ;;
        *)
            pkgs="$pkgs FAudio"
            ;;
    esac

    pkgs="$pkgs SDL3 wxWidgets3.2 zlib binutils cmake crt-git headers-git make pkgconf tools-git windows-default-manifest libmangle-git ninja gdb ccache openal"

    case "$target" in
        *x86_64)
            pkgs="$pkgs extra-cmake-modules"
            ;;
    esac

    [ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs ffmpeg"

    set --
    for p in $pkgs; do
        set -- "$@" "${target}-${p}"
    done

    case "$target" in
        *clang*)
            # We use gcc windres for now, llvm-rc is sometimes broken.
            set -- "$@" mingw-w64-x86_64-binutils
        ;;
    esac

    # install
    check pacman --noconfirm --needed -S git make zip "$@"

    # get the necessary win32 headers
    check git submodule update --init --remote --recursive

    if [ "$MSYSTEM" = MSYS ]; then
        case "$target" in
            *i686)
                pre_build=\
"MSYSTEM=MINGW32 bash -l
cd $(pwd)"
                ;;
            *x86_64)
                pre_build=\
"MSYSTEM=MINGW64 bash -l
cd $(pwd)"
                ;;
        esac
        post_build=exit
    fi

    build_instructions
}

mac_installdeps() {
    if ! xcode-select -p >/dev/null 2>&1 && \
       ! pkgutil --pkg-info=com.apple.pkg.CLTools_Executables >/dev/null 2>&1 && \
       ! pkgutil --pkg-info=com.apple.pkg.DeveloperToolsCLI >/dev/null 2>&1; then

        error 'Please install XCode and the XCode Command Line Tools, then run this script again. On newer systems this can be done with: xcode-select --install   '
    fi

    if command -v brew >/dev/null; then
        brew_installdeps
    elif command -v port >/dev/null; then
        macports_installdeps
    elif command -v fink >/dev/null; then
        fink_installdeps
    else
        error 'You have no package manager, please install homebrew, macports or fink'
    fi
}

brew_installdeps() {
    check_cross
    installing

    check brew -v update

    brews="nasm cmake ccache gettext libtiff pkg-config sdl3 wxwidgets faudio ccache ninja zlib"

    [ -n "$ENABLE_FFMPEG" ] && brews="$brews ffmpeg"

    # This is necessary for the GitHub Actions CI:
    brew -v install python
    brew link --overwrite python

    check brew -v install -f $brews

    for brew in gettext wxwidgets; do
        brew unlink $brew
        brew link   $brew --force
    done

    brew -v cleanup

    build_instructions
}

macports_installdeps() {
    check_cross
    installing

    check sudo port -v selfupdate

    ports="cmake ccache nasm gettext pkgconfig libsdl3 wxWidgets-3.0 libiconv ninja"

    [ -n "$ENABLE_FFMPEG" ] && ports="$ports ffmpeg"

    check sudo port -v install $ports
    check sudo port select wxWidgets wxWidgets-3.0

    build_instructions
}

fink_installdeps() {
    check_cross
    installing

    check sudo fink -vy selfupdate

    pkgs="cmake ccache nasm libgettext8-dev gettext-tools pkgconfig sdl3 wxwidgets300-osxcocoa libiconv-dev ccache ninja"

    [ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs ffmpeg"

    check sudo fink -vy install $pkgs

    build_instructions
}

build_instructions() {
    cat <<EOF

[32mDone! To build do:[0m

$pre_build
mkdir build && cd build
$CMAKE .. -DCMAKE_BUILD_TYPE=Release $cmake_flags -G Ninja
ninja
$post_build

EOF
}

main "$@"

# vim:et sw=4:
