#!/bin/bash

##################################################################
# Custom action script to install/upgrade Mono
#  a. Remove any existing version of Mono installed on a node
#  b. Install specified versioni of Mono (http://www.mono-project.com) on a HDInsight cluster's Node.
##################################################################

set -e

# Note: Can set default version here
declare MONO_VERSION="5.20"

log(){
    local message="${1}"
    local current_time=$(date "+%Y.%m.%d-%H.%M.%S")
    echo "Install-Mono: ${current_time}: ${message}"
}

validate_installation(){
    log "Validating Mono installation for target version $1"
    local MATCH_STR="Mono JIT compiler version $1"
    log "Validating Mono Version $TARGET_VERSION is installed properly"
    local INSTALLED_VERSION_STR=$(mono --version 2>&1 | grep -w "Mono JIT compiler version")
    if [[ $INSTALLED_VERSION_STR != $MATCH_STR* ]] ; then
        log "Failed to detect mono version $1 on machine."
        exit 1
    fi
    
    echo "using System;
    public class HelloWorld
    {
       public static void Main(string[] args)
       {
           Console.WriteLine (\"Hello Mono World\");
       }
    }" > hello.cs
    log "compiling hello.cs"
    csc hello.cs
    
    log "Validating hello.exe exists"
    if [[ ! -f "hello.exe" ]]; then
        echo "hello.exe was not compiled correctly"
        exit 1
    fi
    
    log "verifying mono can run hello.exe"
    mono hello.exe | grep 'Hello Mono World' &> /dev/null
    if [[ $? != 0 ]]; then
        log "mono command did not return correct string"
        exit 1
    fi
    log "Successfully validated that Mono is installed correctly"
}

if [ "$(id -u)" != "0" ]; then
    log  "This script is supposed to be invoked as root."
    exit 1
fi

# Note: It is expected that user's supplying Mono versions validated the version
# exists by checking https://download.mono-project.com/repo/debian/dists/stable-xenial/snapshots/
if [ "$1" != "" ]; then
    MONO_VERSION="$1"
fi

log "Target Mono version to install: $MONO_VERSION"

REPO_CHECK_URL="https://download.mono-project.com/repo/debian/dists/stable-xenial/snapshots/$MONO_VERSION/Release"
if  ! curl -s --head  "$REPO_CHECK_URL" | head -n 1 | grep 200 >/dev/null; then
    log "Mono Version $MONO_VERSION not found at $REPO_CHECK_URL"
    exit 1
fi
log  "Checking for existing Mono version"
if type "mono" > /dev/null; then
    INSTALLED_VERSION_STR=$(mono --version 2>&1 | grep -w "Mono JIT compiler version")
    log  "Installed Version of Mono: ${INSTALLED_VERSION_STR}"
    
    MATCH_STR="Mono JIT compiler version $MONO_VERSION "
    if [[ $INSTALLED_VERSION_STR != $MATCH_STR* ]] ; then
        log  "Uninstalling current version, before installing target version"
        apt-get -y remove --purge --auto-remove mono-runtime
        apt-get -y remove --purge --auto-remove mono-complete
        apt-get -y remove --purge --auto-remove ca-certificates-mono
    else
        log  "Installed version of mono $INSTALLED_VERSION_STR matches target version $MONO_VERSION."
        validate_installation $MONO_VERSION
        
        exit 0
    fi
else
    log  "Mono not found on the system"
fi

log  "Looking for existing mono-official-stable repo sources"
if [ -f /etc/apt/sources.list.d/mono-official-stable.list ]; then
    log  "Removing mono-official-stable repo sources"
    rm /etc/apt/sources.list.d/mono-official-stable.list
fi
log  "Removed existing mono-official-stable repo sources"

log  "Adding Mono GPG keys"
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

log  "Installing ca-certificates-mono package"
apt install apt-transport-https ca-certificates
log  "Installed ca-certificates-mono package"

MONO_RESOURCE_LIST_URL="https://download.mono-project.com/repo/ubuntu stable-xenial/snapshots/$MONO_VERSION main"
log  "Adding Mono package resource list $MONO_RESOURCE_LIST_URL"
echo  "deb $MONO_RESOURCE_LIST_URL" | tee /etc/apt/sources.list.d/mono-official-stable.list

log  "Updating package list"
apt-get update

log  "Installing mono-complete package"
apt-get install -y mono-complete
log  "Installed mono-complete package"

validate_installation $MONO_VERSION

log  "Finished installing Mono version $MONO_VERSION"