#!/bin/sh
set -e
#
# Pegasus for Linux Quick Install script
#
# For the installation steps, including how to verify the contents of
# this file, see:
#
#   https://pegasus.readthedocs.io/en/latest/getting-pegasus/
#
# This script is meant for quick & easy install via:
#
#   $ sudo curl -fsSL https://get.pegasus.org | /bin/bash -s -- --no-dry-run
#

usage() {
    cat <<-EOF
Specify only one of the following:
--dist      : Display detected operating system and exit
-h, --help  : Display this message and exit
--dry-run   : Do not install, just print commands [default]
--no-dry-run: Issue all the commands neeed to install Pegasus
EOF
    exit 0
}

command_exists() {
    command -v "$@" > /dev/null 2>&1
}

is_dry_run() {
    [[ $DRY_RUN ]]
}

is_display_dist() {
    [[ $DIST ]]
}

is_darwin() {
    case "$(uname -s)" in
        *darwin* ) true ;;
        *Darwin* ) true ;;
        * ) false;;
    esac
}


# Check if this is a forked Linux distro
check_forked() {

    if [ "$ID" = 'linuxmint' ]; then
        # Linux Mint is an Ubuntu fork
        ID='ubuntu'
        VERSION_CODENAME=$UBUNTU_CODENAME
        case $VERSION_CODENAME in
            jammy) VERSION_ID=22.04;;
            noble) VERSION_ID=24.04;;
        esac
    elif is_darwin; then
        case ${VERSION_ID%%.*} in
            14) VERSION_CODENAME=Sonoma;;
            15) VERSION_CODENAME=Sequoia;;
        esac
    fi

    if is_display_dist; then
        cat <<-EOF
You're using '$ID' version '$VERSION_ID' codename '$VERSION_CODENAME'.
EOF
        exit 0
    fi
}


get_distribution() {
    if [[ $DISTRIBUTION ]]; then
        #
        # For testing purposes.  DISTRIBUTION is a space-separated tuple:
        #      ${ID} ${VERSION_ID} ${VERSION_CODENAME}
        # where $VERSION_CODENAME number is only set on Debian and Ubuntu.
        # Because the list is space-separated, it must be quoted (or escaped)
        # on the command-line.  The values generated by this script for the
        # supported platforms follow.
        #
        #     debian 11 bullseye
        #     debian 12 bookworm
        #     ubuntu 22 jammy
        #     ubuntu 24 noble
        #     almalinux 8
        #     almalinux 9
        #     rocky 8
        #     rocky 9
        #     opensuse-leap 15
        #     alpine 3
        #     macos 14
        #     macos 15
        #

        set -- $DISTRIBUTION
        ID=$1
        VERSION_ID=$2
        VERSION_CODENAME=$3
        return
    fi

    # Every system that we officially support has /etc/os-release
    if is_darwin; then
        ID="macos"
        VERSION_ID=$(sw_vers -v)
        VERSION_CODENAME=${VERSION_ID}
    else
        . /etc/os-release
    fi

    check_forked

    VERSION_ID=${VERSION_ID%%.*}

    ARCH=$(arch)

    if [[ $SHOW_DISTRIBUTION ]]; then
        echo "${ID} ${VERSION_ID} ${VERSION_CODENAME} ${ARCH}"
        exit 0
    fi
}

update_etc_hosts() {
    if [[ $HOSTS ]]; then
        $sh_c "cat > /tmp/_hosts <<EOT
${HOSTS}
EOT"
        $sh_c "sed -e '/# Kiso: Start/,/# Kiso: End/d' /etc/hosts > /tmp/hosts.new"
        $sh_c "cat /tmp/_hosts >> /tmp/hosts.new"
        $sh_c "vi -c ':1,\$d'  -c 'a|`cat /tmp/hosts.new`' -c ':wq' /etc/hosts"
        $sh_c "rm -f /tmp/_hosts /tmp/hosts.new"
    fi
}

do_install() {
    # Figure out the distribution and version we are running on.
    # This will set $ID and $VERSION_ID.
    get_distribution

    user=$(id -un 2>/dev/null || true)

    if is_dry_run; then
        sh_c="echo"
    elif [ "$user" != 'root' ]; then
        if command_exists sudo; then
            sh_c='sudo -E sh -c'
        elif command_exists su; then
            sh_c='su -c'
        else
            cat >&2 <<-'EOF'
Error: this installer needs the ability to run commands as root.
We are unable to find either "sudo" or "su" available to make this happen.
EOF
            exit 1
        fi
    fi

    case $ID in
        scientific|centos|rhel|almalinux|rocky|suse|opensuse-leap|macos|alpine)
            repo_cmd="dnf --assumeyes install"
            case $ID in
                alpine)
                    repo_cmd="apk add"
                    ;;
                centos|scientific)
                    repo_cmd="yum --assumeyes install"
                    ;;
                suse|opensuse-leap)
                    repo_cmd="zypper --non-interactive install"
                    ;;
            esac
    esac

    # echo
    # echo "# Disable SELinux"
    # if command_exists setenforce; then
    #     $sh_c "setenforce 0"
    # fi

    # echo
    # echo "# Disable Firewall"
    # for i in "iptables firewalld ufw"; do
    #     $sh_c "systemctl stop $i"
    # done

    echo
    echo "# Installing dependencies"
    if ! command_exists sudo; then
        $sh_c "${repo_cmd} sudo findutils" # openssh-server
    fi

    export PATH=${PATH}:/usr/sbin
    echo $PATH

    echo
    echo "# Create a group"
    if ! getent group "kiso" >/dev/null; then
        if ! command_exists groupadd; then
            # Package name shadow-utils is distro specific
            $sh_c "${repo_cmd} shadow-utils"
        fi

        $sh_c "groupadd -f kiso"
    fi

    echo
    echo "# Create a user"
    kiso=$(id -un kiso 2>/dev/null || true)
    if [ "$kiso" != 'kiso' ]; then
        if ! command_exists useradd; then
            # Package name shadow-utils is distro specific
            $sh_c "${repo_cmd} shadow-utils"
        fi

        $sh_c "useradd --create-home --gid kiso --shell /bin/bash kiso"
    fi

    echo
    echo "# Allow passwordless sudo for kiso"
    if command_exists sudo; then
        $sh_c "cat > /etc/sudoers.d/kiso <<EOF
kiso ALL=(ALL) NOPASSWD:ALL
EOF"
    fi

    # echo
    # echo "Copy .ssh dir"
    # if [ "$kiso" != 'kiso' ]; then
    #     $sh_c "mkdir -p ~kiso/.ssh"
    #     $sh_c "touch ~kiso/.ssh/authorized_keys"
    #     $sh_c "chown -R kiso:kiso ~kiso/.ssh"
    #     $sh_c "chmod 700 ~kiso/.ssh"
    #     $sh_c "chmod 600 ~kiso/.ssh/*"
    # fi

    echo
    echo "# Update /etc/hosts"
    if ! command_exists vi; then
        $sh_c "${repo_cmd} vim"
    fi
    update_etc_hosts
}

# Set global defaults
DRY_RUN=1
sh_c='sh -c'
unset DIST

# Process command-line options
while [ $# -gt 0 ]; do
    case $1 in
        --show-distribution)
            SHOW_DISTRIBUTION=TRUE
            ;;
        --distribution)
            DISTRIBUTION=$2
            if [[ ! $DISTRIBUTION ]]; then
                echo "--distribution requires an argument"
                exit 1
            fi
            shift
            ;;
        --no-dry-run)
            unset DRY_RUN
            ;;
        --dry-run)
            DRY_RUN=1
            ;;
        --dist)
            DIST=1
            ;;
        --hosts)
            HOSTS=$2
            shift
            ;;
        --help|-h)
            usage
            ;;
        *)
            echo "Illegal option $1"
            echo "Run $0 --help for usage"
            exit 1
            ;;
    esac
    shift
done

# wrapped up in functions so that we have some protection against only getting
# half the file during "curl | sh"

do_install

exit 0
