#!/bin/bash
set -e

# install.sh
#	This script installs a basic setup for a debian machine

USERNAME=fschl
SUDO="sudo"

check_root() {
    # We need root rights at some point
    if [ "$(whoami)" != "root" ]; then
      if ! which $SUDO >/dev/null; then
        echo "ERROR: $0 is not run as root and $SUDO is not available" >&2
        exit 1
      fi
    else
      SUDO="" # We're already root
    fi
}

apt_sources() {
    #  https://www.debian.org/releases/
    ddist=$1
    DIST="${ddist:-stable}"

    allowed_dists=("testing stable buster bullseye")
    if [ ! ${DIST} in "${allowed_dists[@]}" ]; then
        echo "... $DIST was not in allowed dists... setting to stable"
        DIST="stable"
    fi

    echo "writing /etc/apt/sources.list..."
    echo "using ${DIST}"
    cat <<-EOF > /etc/apt/sources.list
deb http://deb.debian.org/debian/ ${DIST} main
deb-src http://deb.debian.org/debian/ ${DIST} main

deb http://deb.debian.org/debian-security/ ${DIST}-security main
deb-src http://deb.debian.org/debian-security/ ${DIST}-security main

deb http://deb.debian.org/debian ${DIST}-updates main
deb-src http://deb.debian.org/debian ${DIST}-updates main
EOF
}

base_applications() {
    echo "update and installing baseapps..."

    $SUDO apt update
    $SUDO apt upgrade

    DEBIAN_FRONTEND=noninteractive

    $SUDO apt install -y \
        apt-transport-https \
        automake \
        bash-completion \
        bat \
        bmon \
        bzip2 \
        ca-certificates \
        cmake \
        coreutils \
        cryptsetup \
        curl \
        dnsutils \
        fzf \
        gcc \
        git \
        gnupg \
        gnupg-agent \
        gnupg2 \
        grep \
        htop \
        iotop \
        locales \
        linux-headers-$(uname -r) \
        make \
        mount \
        net-tools \
        restic \
        ripgrep \
        rsync \
        ssh \
        sudo \
        tar \
        tmux \
        tree \
        unzip \
        vim \
        vpnc \
        vpnc-scripts \
        wireguard \
        wireguard-dkms \
        wireguard-tools \
        zip \
        --no-install-recommends

    $SUDO restic self-update
    echo "... DONE... cleaning up\n\n"
    $SUDO apt autoremove
    $SUDO apt autoclean
    $SUDO apt clean
}

install_server_base() {
    echo "update and installing server base tools..."

    DEBIAN_FRONTEND=noninteractive

    $SUDO apt update
    $SUDO apt install -y \
        fail2ban \
        logwatch \
        unattended-upgrades \
        --no-install-recommends

    echo "... DONE... cleaning up\n\n"
    $SUDO apt autoremove
    $SUDO apt autoclean
    $SUDO apt clean

    echo "setting up logwatch..."
    echo "... TODO require email to be set as parameter"
    echo "... TODO require email to be set as parameter"
    cat <<-EOF > /etc/cron.daily/00logwatch
/usr/sbin/logwatch --output mail --mailto you@example.com --detail high

EOF
    echo " ... DONE"

    # TODO: is this really needed? or default behavior anyway?
    echo "set unattended upgrades..."
    cat <<-EOF > /etc/apt/apt.conf.d/10periodic
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
EOF

    echo " ... DONE"
}

no_suspend() {
    # https://wiki.debian.org/SystemdSuspendSedation
    $SUDO sed -i "s/HandleLidSwitch=.*/HandleLidSwitch=ignore/" /etc/systemd/logind.conf
    $SUDO sed -i "s/HandleLidSwitchDocked=.*/HandleLidSwitchDocked=ignore/" /etc/systemd/logind.conf
    $SUDO sed -i "s/IdleActionSec=.*/IdleActionSec=90min/" /etc/systemd/logind.conf

    # turn off screen blanking
    # https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=18200&sid=135af53eb82496bc64f4c0eefbc86d2c&start=25
    # http://raspberrypi.stackexchange.com/questions/752/how-do-i-prevent-the-screen-from-going-blank
    xset s noblank

    $SUDO systemctl restart systemd-logind.service
}

install_nvidia_docker() {
    # get latest driver from https://www.nvidia.com/object/unix.html
    # https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(version-2.0)#prerequisites
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
            sudo tee /etc/apt/sources.list.d/nvidia-docker.list
            sudo apt-get update

            # Install nvidia-docker2 and reload the Docker daemon configuration
            sudo apt-get install -y nvidia-docker2
            sudo pkill -SIGHUP dockerd
}

install_latex() {
    $SUDO apt update
    $SUDO apt install -y \
        evince \
        texlive \
        texlive-bibtex-extra \
        texlive-fonts-extra \
        texlive-fonts-recommended \
        texlive-lang-english \
        texlive-lang-german \
        texlive-latex-extra \
        texlive-latex-recommended \
        texlive-pictures \
        texlive-plain-generic \
        zathura \
        --no-install-recommends
}

install_workstation_apps() {
    DEBIAN_FRONTEND=noninteractive

    $SUDO apt update
    $SUDO apt install -y \
        alsa-tools \
        alsa-utils \
        aspell \
        aspell-de \
        aspell-en \
        cups-browsed \
        emacs \
        firefox-esr \
        firmware-iwlwifi \
        firmware-linux-nonfree \
        firmware-realtek \
        fonts-font-awesome \
        fonts-noto \
        fonts-noto-cjk \
        fonts-powerline \
        gimp \
        keepassxc \
        libnotify-bin \
        libnotify-dev \
        libreoffice-calc \
        libreoffice-impress \
        libreoffice-l10n-de \
        libreoffice-l10n-en-gb \
        libreoffice-writer \
        ntfs-3g \
        network-manager \
        network-manager-openvpn \
        nmap \
        openvpn \
        openvpn-systemd-resolved \
        thunderbird \
        thunderbird-l10n-de \
        thunderbird-l10n-en-gb \
        --no-install-recommends

    TARGET="/home/$USERNAME/.emacs.d"
    rm -rf ${TARGET}
    git clone https://github.com/syl20bnr/spacemacs "${TARGET}"
    #    rm -rf "${TARGET}"/private/snippets
    #    git clone https://github.com/AndreaCrotti/yasnippet-snippets "${TARGET}"/private/yas-snippets
    #    ln -s "${TARGET}"/private/yas-snips/snippets "${TARGET}"/private/snippets/
}

install_sway() {
    echo " installing sway and wayland tools..."
    DEBIAN_FRONTEND=noninteractive
    $SUDO apt update
    $SUDO apt install -y \
        brightnessctl \
        mako \
        sway \
        udiskie \
        udisks2 \
        wl-clipboard \
        wob \
        wofi \
        ydotool \
        --no-install-recommends

    mv /home/${USERNAME}/.bashrc /home/${USERNAME}/.bashrc~
    ln -s /home/${USERNAME}/dotfiles/.bashrc /home/${USERNAME}/.bashrc
    cp ../sway/mako.conf /home/${USERNAME}/.config/mako/conf

    (
        git clone https://github.com/Biont/sway-launcher-desktop /home/${USERNAME}/projects/sway-launcher-desktop
    )

    # build swaylock-effects because its not available on Debian
    # https://github.com/voidgloom/swaylock-effects
    (
        $SUDO apt update
        $SUDO apt install -y \
            wayland-protocols \
            libwayland-client++0 \
            libcairo2-dev \
            libwayland-client0 \
            --no-install-recommends

        TARGET=/home/${USERNAME}/projects/swaylock-effects
        git clone https://github.com/voidgloom/swaylock-effects ${TARGET}
        cd ${TARGET}
        meson build && ninja -C build && sudo ninja -C build install
        $SUDO chmod a+s /usr/local/bin/swaylock
    )

}

install_i3() {
    echo "Xorg with i3wm and some tools..."

    # check if CJK and other eastern letters are displayed correctly:
    # https://meta.wikimedia.org/wiki/List_of_Wikipedias

    DEBIAN_FRONTEND=noninteractive

    $SUDO apt update
    $SUDO apt install -y \
        feh \
        fswebcam \
        i3 \
        i3lock \
        i3lock-fancy \
        i3status \
	      lightdm \
        network-manager-gnome \
        network-manager-vpnc \
        network-manager-vpnc-gnome \
        remmina \
        rxvt-unicode \
        scrot \
        shotwell \
        suckless-tools \
        vlc \
        xdotool \
        xorg \
        --no-install-recommends

    # for f in (); do
    #     ln -s $f /home/$USER/$f
    # done

    echo "... setting capslock to control"
    $SUDO sed -i "s/^XKBOPTIONS=.*/XKBOPTIONS=\"ctrl:nocaps\"/" /etc/default/keyboard

}

install_syncthing() {
    # install Syncthing via https://apt.syncthing.net/
    # Add the release PGP keys:
    curl -s https://syncthing.net/release-key.txt | sudo apt-key add -

    # Add the "stable" channel to your APT sources:
    cat "deb https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list

    # pin the correct apt repo
    printf "Package: *\nPin: origin apt.syncthing.net\nPin-Priority: 990\n" | sudo tee /etc/apt/preferences.d/syncthing

    # Update and install syncthing:
    $SUDO apt-get update
    $SUDO apt-get install -y syncthing
    echo "... DONE... cleaning up\n\n"
    $SUDO apt autoremove
    $SUDO apt autoclean
    $SUDO apt clean

    echo "enable and start the syncthing per-user service for ${USERNAME}"
    $SUDO cp ../etc/systemd/system/syncth* /etc/systemd/system/
    user=${USERNAME}
    $SUDO systemctl daemon-reload
    $SUDO systemctl enable syncthing@${USERNAME}
    $SUDO systemctl start syncthing@${USERNAME}.service
    systemctl status syncthing@${USERNAME}.service

    no_suspend

    echo "... setting capslock to control"
    sed -i "s/^XKBOPTIONS=.*/XKBOPTIONS=\"ctrl:nocaps\"/" /etc/default/keyboard

    TARGET="/home/$USERNAME/.emacs.d"
    git clone https://github.com/syl20bnr/spacemacs "${TARGET}"
    #rm -rf "${TARGET}"/private/snippets
    #git clone https://github.com/AndreaCrotti/yasnippet-snippets "${TARGET}"/private/yas-snips
    #ln -s "${TARGET}"/private/yas-snips/snippets "${TARGET}"/private/snippets/

}

link_userdirs() {

    mount_dir=$1
    target_mount="${mount_dir:-/mnt/docs/}"
    user_dirs=("Documents Downloads Music Pictures Videos")
    for DIR in $user_dirs
    do
        echo "removing and linking ${DIR}..."
        rm -rfv /home/$USERNAME/$DIR
        echo "link target: ${target_mount}/${DIR}"
        ln -vs ${target_mount}/${DIR} /home/${USERNAME}/${DIR}
    done

    projects_mount=$docs_mount
}

install_vscodium() {
    # https://vscodium.com/

    wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg | sudo apt-key add -

    echo 'deb https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/repos/debs/ vscodium main' | sudo tee --append /etc/apt/sources.list.d/vscodium.list

    $SUDO apt update
    $SUDO apt install -y \
        codium \
        --no-install-recommends

    codium version

    # ms-azuretools.vscode-docker
    # ms-vscode.go
    # vscodevim.vim
}

install_wine() {

    # https://wiki.winehq.org/Debian
    curl https://dl.winehq.org/wine-builds/winehq.key | gpg --dearmor > /etc/apt/trusted.gpg.d/winehq.gpg
    echo 'deb https://dl.winehq.org/wine-builds/debian/ bookworm main' | sudo tee /etc/apt/sources.list.d/wine.list

    $SUDO sudo dpkg --add-architecture i386
    $SUDO apt update
    $SUDO apt install \
        winehq-staging \
        --install-recommends

    wine --version

}

install_docker() {
    # https://docs.docker.com/install/linux/docker-ce/debian/#install-using-the-repository

    # bad experiences with static binaries...
    # https://docs.docker.com/engine/installation/binaries/#install-static-binaries
    echo "installing docker binary Version $VERS ..."
    # https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount

    $SUDO apt install -y \
            apt-transport-https \
            ca-certificates \
            curl \
            gnupg2 \
            software-properties-common \
            --no-install-recommends

    curl -fsSL https://download.docker.com/linux/debian/gpg | $SUDO apt-key add -

    # add docker apt repo
    cat <<-EOF > /etc/apt/sources.list.d/docker.list
    deb [arch=amd64] https://download.docker.com/linux/debian buster stable
    # deb [arch=amd64] https://download.docker.com/linux/debian buster test
    # deb [arch=amd64] https://download.docker.com/linux/debian buster nightly
EOF

    $SUDO apt update
    $SUDO apt install -y \
        docker-ce \
        --no-install-recommends

    $SUDO usermod -aG docker ${USERNAME}

    docker version
    docker info
}

install_compose() {
    # https://github.com/docker/compose/releases
    # btw: *not* for raspbian! you got 3 choices: hypriot, install via pip or build yourself
    # https://www.berthon.eu/2017/getting-docker-compose-on-raspberry-pi-arm-the-easy-way/
    VERS="1.29.2"
    FILE="docker-compose-$(uname -s)-$(uname -m)"
    echo "installing docker-compose $VERS ... curling from github"

    curl -SL "https://github.com/docker/compose/releases/download/${VERS}/${FILE}" -o /tmp/${FILE}
    curl -SL "https://github.com/docker/compose/releases/download/${VERS}/${FILE}.sha256" -o /tmp/${FILE}.sha256

    if [ ! $(cat /tmp/${FILE}.sha256 | sha256sum -c -) ]; then
        echo "... checksum failed... stopping"
        exit 1;
    fi

    chmod +x /tmp/${FILE}
    mv /tmp/${FILE} /usr/bin/docker-compose
    rm /tmp/${FILE}.sha256

    echo "... done"

    /usr/bin/docker-compose version
}

install_nvidia() {
    echo "Prepare install for NVIDIA proprietary display driver"

    apt update
    apt install -y \
        gcc \
        linux-source \
        linux-headers-`uname -r` \
        --no-install-recommends

    echo ""
    echo "Please find a link to the current Package"
    echo "  https://devtalk.nvidia.com/default/topic/533434/linux/current-graphics-driver-releases/"
    echo ""
    echo "1. Download the self extracting archive. (*.run)"
    echo "2. reboot into recovery mode and login as root"
    echo "3. sh DRIVER_ARCHIVE.run"
    echo ""
    echo "... check if driver was installed correctly: $ nvidia-smi"
    echo "more information can be found in README at link above"

    echo ""
    echo "Install NVIDIA-docker"
    echo ""
    echo "since Docker 19.03 no additional runtime required."
    echo "  https://github.com/NVIDIA/nvidia-docker"

    # https://nvidia.github.io/nvidia-docker/
    distribution="debian10"

    curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    apt update
    apt install -y nvidia-container-toolkit
    systemctl restart docker
    docker pull nvidia/cuda:9.0-base

    echo ""
    echo "... check if driver was installed correctly: "
    echo "$ docker run --gpus all nvidia/cuda:9.0-base nvidia-smi"
    echo "   should give same output as above"
}

install_virtualbox() {
    # https://wiki.debian.org/VirtualBox#Installation_of_non-free_edition
    $SUDO apt install -y \
            apt-transport-https \
            ca-certificates \
            curl \
            gnupg2 \
            software-properties-common \
            --no-install-recommends

    curl -fsSL https://download.docker.com/linux/debian/gpg | $SUDO apt-key add -

    # add docker apt repo
    cat <<-EOF > /etc/apt/sources.list.d/docker.list
    deb [arch=amd64] https://download.docker.com/linux/debian buster stable
    # deb [arch=amd64] https://download.docker.com/linux/debian buster test
    # deb [arch=amd64] https://download.docker.com/linux/debian buster nightly
EOF

}

# install/update golang from source
install_golang() {
    export GO_VERSION=1.18
    export GO_SRC=/usr/local/go

    # if we are passing the version
    if [[ ! -z "$1" ]]; then
        export GO_VERSION=$1
    fi

    (
        curl -sSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | $SUDO tar -v -C /usr/local -xz
    )
}

install_rust() {
    echo "... rustup.sh ... "
    curl --proto 'https' --tlsv1.2 https://sh.rustup.rs | sh

    echo "... adding dependencies for alacritty and i3status-rs ... "
    $SUDO apt install -y \
         cmake \
         fonts-font-awesome \
         gcc \
         pkg-config \
         libdbus-1-dev \
         libfreetype6-dev \
         libfontconfig1-dev \
         libssl-dev \
         libxcb-xfixes0-dev \
         libxkbcommon-dev \
         python3 \
         --no-install-recommends

    cargo install du-dust

    (
        mkdir -p "/home/$USERNAME/projects"
        TARGET="/home/$USERNAME/projects/i3status-rust"
        git clone https://github.com/greshake/i3status-rust ${TARGET}
        cd ${TARGET}
        cargo install --path .
        ./install.sh
    )
}

main() {
    local cmd=$1

    if [[ -z "$cmd" ]]; then
        echo "Usage: \n base (incl docker+compose)| i3 | sway | server | latex | update-docker | vscode | go | rust"
    fi

    case "$cmd" in
        base)
            base_applications
            install_docker
            install_compose
            ;;
        server)
            base_applications
            install_server_base
            install_docker
            install_compose
            ;;
        i3)
            base_applications
            install_syncthing
            install_i3
            install_workstation_apps
            ;;
        sway)
            base_applications
            install_syncthing
            install_sway
            install_workstation_apps
            ;;
        links)
            link_userdirs /mnt/docs/
            ;;
        latex)
            install_latex
            ;;
        vscode)
            install_vscodium
            ;;
        update-docker)
            install_docker
            install_compose
            ;;
        go)
            install_golang
            ;;
        rust)
            install_rust
            ;;
        syncthing)
            install_syncthing
            ;;
        wine)
            install_wine
            ;;
    esac
}

main "$@"