#!/bin/bash

set -e

function showHelp() {
  cat << HELP
  🧙 arkanum ✨🌌☄️💥 is used to install optional runtimes for developing in a
  code-server container environment.

  Syntax: arkanum RUNTIME ...
  RUNTIME         [dotnet|golang|nodejs|powershell]
    dotnet               Installs latest LTS dotnet core sdk + runtime.
    gitea                Installs gitea tools like the changelog generator.
    golang               Installs golang 1.19.3.
    nodejs               Installs latest NodeJs LTS version.
    powershell           Installs latest PowerShell LTS version.
  --disable-motd         Disables hint in new bash terminal.
  --install-extensions   Installs predefined recommended extensions.
  --reset-codesetting    Sets VS Code user setting with basic (Fira Code).
  -h                     Prints this help message.

  Example 1: arkanum dotnet
  Example 2: arkanum golang nodejs
  Example 3: arkanum --disable-motd
HELP
}

function disableMotd() {
  if [[ -e "$HOME/enable_motd" ]]; then
    say "Disabling 'arkanum' motd..." "disableMotd"
    rm -f "$HOME/enable_motd"
  fi
}

function say() {
  if [[ -n "$2" ]]; then
    echo -e "🧙 \e[32markanum\e[0m \e[34m[⚒️ $2]\e[0m: $1"
  else
    echo -e "🧙 \e[32markanum\e[0m: $1"
  fi
}

function sayE() {
  if [[ -n "$2" ]]; then
    echo -e "🧙 \e[31markanum\e[0m \e[34m[⚒️ $2]\e[0m: $1" 1>&2
  else
    echo -e "🧙 \e[31markanum\e[0m: $1" 1>&2
  fi
}

function instDotNet() {
  say "Installing dotnet requirements..." "dotnet"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install --no-install-recommends -y \
    libicu70

  say "Downloading latest install script..." "dotnet"
  curl -#fSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
  chmod +x /tmp/dotnet-install.sh

  say "Installing latest .NET Core LTS release..." "dotnet"
  /tmp/dotnet-install.sh --channel LTS
  echo 'export PATH=$PATH:/config/.dotnet' | sudo tee -a /etc/bash.bashrc > /dev/null

  say "Cleaning up..." "dotnet"
  sudo -E apt-get clean
  sudo rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*
  say "dotnet done. " "dotnet"
}

function instGoLang() {
  if [[ -z "$1" ]]; then
    GOVERSION="1.19.3"
  else
    GOVERSION="$1"
  fi

  say "Downloading golang ($GOVERSION)..." "GoLang"
  curl -#fSL "https://go.dev/dl/go$GOVERSION.linux-amd64.tar.gz" -o /tmp/golang.tar.gz
  say "Installing golang ($GOVERSION)...." "GoLang"
  sudo rm -rf /usr/local/go
  sudo tar -C /usr/local -xzf /tmp/golang.tar.gz
  echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /etc/bash.bashrc > /dev/null
  say "Cleaning up..." "GoLang"
  rm -f /tmp/golang.tar.gz
  say "done." "GoLang"
  say "Please reload bash profile to finalize." "GoLang"
}

function instNodeJs() {
  say "Adding nodesource package source (NodeJS LTS)..." "NodeJs"
  curl -#fSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
  say "Updating package lists and installing NodeJS LTS..." "NodeJs"
  sudo -E apt-get install --no-install-recommends -y \
    nodejs

  say "Cleaning up..." "NodeJs"
  sudo -E apt-get clean
  sudo rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*

  say "done." "NodeJs"
}

function instPwsh() {
  say "Installing PowerShell requirements..." "PowerShell"
  sudo -E apt-get install --no-install-recommends -y \
    apt-transport-https \
    software-properties-common

  say "Adding powershell package sources..." "PowerShell"
  # Download the Microsoft repository GPG keys
  curl -#fSL "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" -o /tmp/packages-microsoft-prod.deb
  # Register the Microsoft repository GPG keys
  sudo dpkg -i /tmp/packages-microsoft-prod.deb
  # Update the list of packages after we added packages.microsoft.com
  sudo -E apt-get update

  say "Installing PowerShell..." "PowerShell"
  # Install PowerShell
  sudo -E apt-get install --no-install-recommends -y powershell

  say "done." "PowerShell"
}

function instGiteaTools() {
  TEA_VERSION="0.9.0"
  CHANGELOG_VERSION="main"
  say "Installing Gitea tools..." "Gitea"

  say "Downloading 'changelog' ($CHANGELOG_VERSION)..." "Gitea"
  sudo -E curl -#fSL "https://dl.gitea.io/changelog-tool/$CHANGELOG_VERSION/changelog-$CHANGELOG_VERSION-linux-amd64" -o /usr/bin/changelog
  sudo chmod +x /usr/bin/changelog
  say "'changelog' command installed." "Gitea"

  say "Downloading 'tea' ($TEA_VERSION)..." "Gitea"
  sudo -E curl -#fSL https://dl.gitea.io/tea/$TEA_VERSION/tea-$TEA_VERSION-linux-amd64 -o /usr/bin/tea
  sudo chmod +x /usr/bin/tea
  say "'tea' command installed." "Gitea"

  say "done." "Gitea"
}

function instCodeExtension() {
  say "Downloading required extensions...." "Extension"
  # Gitlens
  say "Downloading 'gitlens'..." "Extension"
  curl -#fSL https://open-vsx.org/api/eamodio/gitlens/13.1.1/file/eamodio.gitlens-13.1.1.vsix -o /tmp/eamodio.gitlens-13.1.1.vsix
  say "Installing 'gitlens'..." "Extension"
  install-extension /tmp/eamodio.gitlens-13.1.1.vsix
  say "Cleaning up 'gitlens' install files" "Extension"
  rm -f /tmp/eamodio.gitlens-13.1.1.vsix

  # OneDarkPro
  say "Downloading 'One Dark Pro' theme..." "Extension"
  curl -#fSL https://open-vsx.org/api/zhuangtongfa/material-theme/3.15.6/file/zhuangtongfa.material-theme-3.15.6.vsix -o /tmp/zhuangtongfa.material-theme-3.15.6.vsix
  say "Installing 'One Dark Pro' theme..." "Extension"
  install-extension /tmp/zhuangtongfa.material-theme-3.15.6.vsix
  say "Cleaning up 'One Dark Pro' install files" "Extension"
  rm -f /tmp/zhuangtongfa.material-theme-3.15.6.vsix

  # vscode-icons
  say "Downloading 'vscode-icons' theme..." "Extension"
  curl -#fSL https://open-vsx.org/api/vscode-icons-team/vscode-icons/12.0.1/file/vscode-icons-team.vscode-icons-12.0.1.vsix -o /tmp/vscode-icons-team.vscode-icons-12.0.1.vsix
  say "Installing 'vscode-icons' theme..." "Extension"
  install-extension /tmp/vscode-icons-team.vscode-icons-12.0.1.vsix
  say "Cleaning up 'vscode-icons' install files" "Extension"
  rm -f /tmp/vscode-icons-team.vscode-icons-12.0.1.vsix

  say "done." "Extension"
}
function setCodeSettings() {
  CODEFILE="$HOME/data/User/settings.json"

  # VSCode user settings file
  say "Setting VScode base settings.($CODEFILE)" "VSCode"
  cat <<EOF | tee "$CODEFILE"
{
  "window.menuBarVisibility": "compact",
  "workbench.colorTheme": "One Dark Pro Darker",
  "workbench.iconTheme": "vscode-icons",
  "editor.fontFamily": "'FiraCode', 'FiraCode Nerd Font', 'FiraCode NF', Consolas, 'Courier New', monospace",
  "terminal.integrated.fontFamily": "'FiraCode Mono', 'FiraCode Nerd Font Mono', 'FiraCode NFM', Consolas, monospace",
  "editor.fontLigatures": true,
  "editor.formatOnSave": true,
  "extensions.autoUpdate": false,
  "git.confirmSync": false,
  "telemetry.telemetryLevel": "off"
}
EOF
  say "done." "VSCode"
}

function main() {
  if [[ "$#" == "0" ]]; then
    showHelp
    exit 0
  fi

  for i in $@; do
    if [[ "$1" == "-h" ]]; then
      showHelp
      exit 0
    elif [[ "$i" == "dotnet" ]]; then
      instDotNet
    elif [[ "$i" == "golang" ]]; then
      instGoLang
    elif [[ "$i" == "nodejs" ]]; then
      instNodeJs
    elif [[ "$i" == "powershell" ]]; then
      instPwsh
    elif [[ "$i" == "gitea" ]]; then
      instGiteaTools
    elif [[ "$i" == "--disable-motd" ]]; then
      disableMotd
      exit 0
    elif [[ "$i" == "--install-extensions" ]]; then
      instCodeExtension
      exit 0
    elif [[ "$i" == "--reset-codesetting" ]]; then
      setCodeSettings
      exit 0
    else
      sayE "Unknown parameter value given!($i)."
      showHelp
      exit 1
    fi
  done
}

main $@
