#!/usr/bin/env bash
# Copyright (c) Alachisoft and contributors. All rights reserved.
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
# This script is inspired from https://github.com/dotnet/install-scripts

# Stop script on NZEC
set -e
# Stop script if unbound variable found (use ${var:-} if intentional)
set -u
# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
# This is causing it to fail
set -o pipefail

# Use in the the functions: eval $invocation
invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'

# standard output may be used as a return value in the functions
# we need a way to write text on the screen in the functions so that
# it won't interfere with the return value.
# Exposing stream 3 as a pipe to standard output of the script itself
exec 3>&1

# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors.
# See if stdout is a terminal
if [ -t 1 ] && command -v tput > /dev/null; then
    # see if it supports colors
    ncolors=$(tput colors)
    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
        bold="$(tput bold       || echo)"
        normal="$(tput sgr0     || echo)"
        black="$(tput setaf 0   || echo)"
        red="$(tput setaf 1     || echo)"
        green="$(tput setaf 2   || echo)"
        yellow="$(tput setaf 3  || echo)"
        blue="$(tput setaf 4    || echo)"
        magenta="$(tput setaf 5 || echo)"
        cyan="$(tput setaf 6    || echo)"
        white="$(tput setaf 7   || echo)"
    fi
fi
#--------------------------------------------------------------------
say_warning() {
    printf "%b\n" "${yellow:-}WARNING: $1${normal:-}" >&3
}

say_err() {
    printf "%b\n" "${red:-}ERROR: $1${normal:-}" >&2
}

say_info() {
    printf "%b\n" "${cyan:-}INFO: $1${normal:-}" >&3
}

say() {
    # using stream 3 (defined in the beginning) to not interfere with stdout of functions
    # which may be used as return value
    printf "%b\n" "${normal:-} $1" >&3
}

say_verbose() {
    if [ "$verbose" = true ]; then
        say "$1"
    fi
}
#--------------------------------------------------------------------
to_lowercase() {
    #eval $invocation

    echo "$1" | tr '[:upper:]' '[:lower:]'
    return 0
}

# args:
# input - $1
remove_trailing_slash() {
    #eval $invocation

    local input="${1:-}"
    echo "${input%/}"
    return 0
}

# args:
# input - $1
remove_beginning_slash() {
    #eval $invocation

    local input="${1:-}"
    echo "${input#/}"
    return 0
}

#--------------------------------------------------------------------
get_os_info() {
	if [ -f /etc/os-release ]; then
		#-- freedesktop.org and systemd
		. /etc/os-release
		OS=$ID
		VER=$VERSION_ID
	elif type lsb_release >/dev/null 2>&1; then
		#-- linuxbase.org
		OS=$(lsb_release -si)
		VER=$(lsb_release -sr)
	elif [ -f /etc/lsb-release ]; then
		#-- For some versions of Debian/Ubuntu without lsb_release command
		. /etc/lsb-release
		OS=$DISTRIB_ID
		VER=$DISTRIB_RELEASE
	elif [ -f /etc/debian_version ]; then
		#-- Older Debian/Ubuntu/etc.
		OS=Debian
		VER=$(cat /etc/debian_version)
	# elif [ -f /etc/SuSe-release ]; then
		#-- Older SuSE/etc.
		# ...
	# elif [ -f /etc/redhat-release ]; then
		# --Older Red Hat, CentOS, etc.
		# ...
	# else
		#-- Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
		# OS=$(uname -s)
		# VER=$(uname -r)
	fi
}
#--------------------------------------------------------------------
install_pre_reqs() {
	#--- https://docs.microsoft.com/en-us/dotnet/core/install/linux
	#--- https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7.1

	say_verbose "install_pre_reqs > OS: $1, VER: $VER"
	local os_name="$(to_lowercase "$1")"
	say_verbose "OS Name (lowercase): $os_name"

	if [ $os_name == "ubuntu" ]; then
		#--- (sajid says) Need to put the check on $VER >= 16.04
		say_verbose "install_pre_reqs > https://packages.microsoft.com/config/ubuntu/$VER/packages-microsoft-prod.deb"

		apt install -y wget apt-transport-https software-properties-common
		wget https://packages.microsoft.com/config/ubuntu/$VER/packages-microsoft-prod.deb
		dpkg -i packages-microsoft-prod.deb
		apt update && apt install -y $runtime powershell

		return 0
	elif [ $os_name == "debian" ]; then
		#--- (sajid says) Need to put the check on $VER >= 9
		say_verbose "install_pre_reqs > https://packages.microsoft.com/config/debian/$VER/packages-microsoft-prod.deb"

		apt install -y wget
		wget https://packages.microsoft.com/config/debian/$VER/packages-microsoft-prod.deb
		dpkg -i packages-microsoft-prod.deb
		apt update && apt install -y $runtime powershell

		return 0
	elif [ $os_name == "rhel" ] || [ $os_name == "centos" ]; then
		#--- (sajid says) Need to put the check on $VER >= 7
		say_verbose "install_pre_reqs > https://packages.microsoft.com/config/rhel/$VER/prod.repo"

		rpm --import https://packages.microsoft.com/keys/microsoft.asc
		yum install -y curl 
		curl https://packages.microsoft.com/config/rhel/$VER/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo
		yum install -y $runtime powershell

		return 0
	elif [ $os_name == "fedora" ]; then
		#--- (sajid says) Need to put the check on $VER >= 29
		VER=7 #-- Fedora 29 or later
		say_verbose "install_pre_reqs > https://packages.microsoft.com/config/rhel/$VER/prod.repo"

		rpm --import https://packages.microsoft.com/keys/microsoft.asc
		yum install -y curl 
		curl https://packages.microsoft.com/config/rhel/$VER/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo
		yum install -y $runtime powershell

		return 0
	fi

	say_verbose "install_pre_reqs > End of Story!"
	return 1
}
#--------------------------------------------------------------------
#-- MAIN
#--------------------------------------------------------------------
args=("$@")

channel="LTS"
version="6.0"
runtime="dotnet-runtime-$version"
verbose=false
dry_run=false
non_dynamic_parameters=""

script_name=$(basename "$0")
#--------------------------------------------------------------------
while [ $# -ne 0 ]
do
    name="$1"
    case "$name" in
        -c|--channel|-[Cc]hannel)
            shift
            channel="$1"
            ;;
        -v|--version|-[Vv]ersion)
            shift
            version="$1"
            runtime="$runtime-$1"
			say "version: $version, runtime: $runtime"
            ;;
        --dry-run|-[Dd]ry[Rr]un)
            dry_run=true
            ;;
        --verbose|-[Vv]erbose)
            verbose=true
            non_dynamic_parameters+=" $name"
            ;;
        -?|--?|-h|--help|-[Hh]elp)
            echo "NCache Pre-reqs Installer"
            echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]"
            echo "       $script_name -h|-?|--help"
            echo ""
            echo "$script_name is a simple command line interface for obtaining dotnet cli."
            echo ""
            echo "Options:"
            echo "  -c,--channel <CHANNEL>         Download from the channel specified, Defaults to \`$channel\`."
            echo "      -Channel"
            echo "          Possible values:"
            echo "          - Current - most current release"
            echo "          - LTS - most current supported release"
            echo "          - 2-part version in a format A.B - represents a specific release"
            echo "              examples: 2.0; 1.0"
            echo "          - Branch name"
            echo "              examples: release/2.0.0; Master"
            echo "          Note: The version parameter overrides the channel parameter."
            echo "  -v,--version <VERSION>         Use specific VERSION, Defaults to \`$version\`."
            echo "      -Version"
            echo "          Possible values:"
            echo "          - latest - most latest build on specific channel"
            echo "          - 3-part version in a format A.B.C - represents specific version of build"
            echo "              examples: 2.0.0-preview2-006120; 1.1.0"
            echo ""
            echo "  --dry-run, -DryRun                  Do not perform installation."
			echo "  --verbose, -Verbose                 Display diagnostics information."
	    ;;
        *)
            say_err "Unknown argument \`$name\`"
            exit 1
            ;;
    esac

    shift
done
#--------------------------------------------------------------------
# if [ "$dry_run" = true ]; then
    # say "Payload URLs:"
    # say "Primary named payload URL: $download_link"
    # if [ "$valid_legacy_download_link" = true ]; then
        # say "Legacy named payload URL: $legacy_download_link"
    # fi
    # repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
    # if [[ "$runtime" == "dotnet" ]]; then
        # repeatable_command+=" --runtime "\""dotnet"\"""
    # elif [[ "$runtime" == "aspnetcore" ]]; then
        # repeatable_command+=" --runtime "\""aspnetcore"\"""
    # fi
    # repeatable_command+="$non_dynamic_parameters"
    # say "Repeatable invocation: $repeatable_command"
    # exit 0
# fi
#--------------------------------------------------------------------

get_os_info

#--- Make sure only root user can run our script
if [ "$(id -u)" != "0"  ] ; then
	say_err "Installation requires root privileges."
	say_info "Run this script as follows:\n\tsudo ./$script_name\n"
	exit 1
fi

install_pre_reqs $OS $VER

say "Installation finished."
