#!/bin/bash

# CV3STA-209 : apt fix
# https://askubuntu.com/questions/908800/what-does-this-apt-error-message-download-is-performed-unsandboxed-as-root
sudo chown -Rv _apt:root /var/cache/apt/archives/partial/
sudo chmod -Rv 700 /var/cache/apt/archives/partial/


# Include scripts
scriptPath=$(dirname "${BASH_SOURCE[0]}")

. "$scriptPath/common.sh"

displayEndInstallation(){

    configuration="${1}"
    endStatus="${2}"
    endMessage="${3}"
    
    displayEnd "Installation" "${configuration}" "${endStatus}" "${endMessage}"
}

# Log to history log
displayEndInstallation "N/A" "Start"

# Set default log file
logFolder="${HOME}/installation"
logFile="${logFolder}/installation.log"

mkdir "$logFolder"
sudo touch "$logFile"
sudo chmod a+rw "$logFile"

skipInstall=false
skipUninstall=false

LogAndOutputToZenity "Getting arguments..."
# the script arguments can be used to override following dialogboxes
# If no argument then we will display the dialogboxes to set those parameters
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
    -r|--repository)
    Repository="$2"
    shift # past argument
    shift # past value
    ;;
    -o|--operator)
    Operator="$2"
    shift # past argument
    shift # past value
    ;;
    -c|--component)
    Component="$2"
    shift # past argument
    shift # past value
    ;;
    -m|--machineName)
    MachineName="$2"
    shift
    shift
    ;;
    -p|--password)
    Password="$2"
    shift
    shift
    ;;
    -P|--project)
    Project="$2"
    shift
    shift
    ;;
    -su|--skip-uninstall)
    skipUninstall="$2"
    shift
    shift
    ;;
    -si|--skip-install)
    skipInstall="$2"
    shift
    shift
    ;;
    -g|--group)
    Group="$2"
    shift
    shift
    ;;
    *)    # unknown option
    POSITIONAL+=("$1") # save it in an array for later
    shift # past argument
    ;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters


# Install last certificates versions
sudo apt-get install -qq -y ca-certificates 2>&1 >> $logFile

# First check internet connection
LogAndOutputToZenity "Checking internet connexion"

check_internet >/dev/null 2>&1
internet=$?

if [ ${internet} != 0 ]; then
    message="$internet Internet connection failed"
    show_error "$message"
    displayEndInstallation "N/A" "Finished - Error" "$message"
    exit 1
fi

# First we need to ask password to the user
while [[ -z $Password ]];do
    if Password=`zenity --password --title='Enter installation password' --text='Please enter the password for the installation'`
    then

        if [[ -z $Password ]]; then
            show_error "No password entered"
            continue
        fi

        # Check password
        hash=$(printf "${Password}" | md5sum)
        foundLine=$(cat ./passwords | grep $hash)
        if [[ -z $foundLine ]]; then
            Password=""
            show_error "Invalid password"
        fi

    else
        LogAndOutputToZenity "Canceled"
        displayEndInstallation "N/A" "Finished - Error" "Canceled on password"
        exit 1
    fi
done

# Check password
# We do this again here to make sure we check it even if it has been passed as argument
hash=$(printf "${Password}" | md5sum)
foundLine=$(cat ./passwords | grep $hash)
if [[ -z $foundLine ]]; then
    Password=""
    show_error "Invalid password"
    exit 1
fi

# Uninstall if needed
if [[ $skipUninstall != true ]]; then
    source ./uninstall.sh
    result=$?
else
    LogAndOutputToZenity "Skipping uninstall"
    result=0
fi

# Reset log file
logFolder="${HOME}/installation"
logFile="${logFolder}/installation.log"

if [ $result != 0 ]; then
    displayEndInstallation "N/A" "Finished - Error" "Error on uninstall"
    exit 1
fi

# Get corresponding profile
profile=$(echo $foundLine | grep -Po "(\w)*(?==)")
if [[ -z $profile ]]; then
    message="Cannot find corresponding profile"
    show_error "$message"
    displayEndInstallation "N/A" "Finished - Error" "$message"
    exit 1
fi
LogAndOutputToZenity "User authentified as $profile"
LogAndOutputToZenity "Installing..."


# Get profile rights for components
rightsSectionName="components"
componentsRights=$(cat ./rightsComponents | grep -Poz "(?<=$rightsSectionName:{\n)([\S\s]*)([\S\s]*)(?=})" | tr -d '\0')
# If rights are set then we need to filter components
if [[ -n $componentsRights ]]; then
    rights=$(echo $componentsRights | grep -Po "(?<=$profile:)([^;]*)(?=;)")
    if [[ $rights != ".*" ]]; then
        Component="$rights"
    fi
fi

# Get profile rights for operators
rightsSectionName="operators"
operatorsRights=$(cat ./rightsOperators | grep -Poz "(?<=$rightsSectionName:{\n)([\S\s]*)([\S\s]*)(?=})" | tr -d '\0')
# If rights are set then we need to filter components
if [[ -n $operatorsRights ]]; then
    rights=$(echo $operatorsRights | grep -Po "(?<=$profile:)([^;]*)(?=;)")
    if [[ $rights != ".*" ]]; then
        Operator="$rights"
    fi
fi

# Get profile rights for groups //external or group
rightsSectionName="groups"
groupsRights=$(cat ./rightsGroups | grep -Poz "(?<=$rightsSectionName:{\n)([\S\s]*)([\S\s]*)(?=})" | tr -d '\0')
# If rights are set then we need to filter components
if [[ -n $groupsRights ]]; then
    rights=$(echo $groupsRights | grep -Po "(?<=$profile:)([^;]*)(?=;)")
    if [[ $rights != ".*" ]]; then
        Group="$rights"
    fi
fi

if [[ -n $Component && -n $Operator && -n $Group ]]; then
    #Group="group"
    Project="revolution"
else
    Component="$2"
    Operator="$2"
    Group="$2"
fi

if [[ -z $Group ]]; then

    # Gather all groups
    i=0
    groupsArg=""
    while read -r line
    do
        prefix="FALSE "
        if [[ $i == 0 ]]; then
            prefix="TRUE "
        fi
        
        groupsArg="${groupsArg}${prefix}${line} "
        i=$((i+1))
    done < <(curl -s https://debs.photo-me.eu/installation/dependencies/ | grep -Po "(?<=>)(\w*-*\w*)(?=\/<)")

    Group=$(zenity --list --width=500 --height=350 --radiolist --title "Select group" --text="Available groups:" --column="" --column="Group" ${groupsArg})
fi

if [[ -z $Group ]]; then
    message="No group chosen"
    show_error "$message"
    displayEndInstallation "N/A" "Finished - Error" "$message"
    exit 1
fi

logThis "User chose group $Group" "INFO" false

# some projects have aliases
declare -A projectAliases
projectAliases=([revolution]="compact v3")

if [[ -z $Project ]]; then
    # Gather all projects
    i=0
    projectsArg=()
    while read -r line
    do
        prefix=FALSE
        if [[ $i == 1 ]]; then
            prefix=TRUE
        fi

        # Use alias if it exists
        if [[ -v projectAliases[$line] ]]; then 
            logThis "alias found for $line : ${projectAliases[$line]}" "DEBUG" false
            line="${projectAliases[$line]}"
        fi
        
        projectsArg+=("${prefix}")
        projectsArg+=("${line}")

        logThis "line : $line, prefix : $prefix, projectsArg : ${projectsArg[@]}" "DEBUG" false
        i=$((i+1))
    done < <(curl -s https://debs.photo-me.eu/installation/dependencies/${Group}/laundry/ | grep -Po "(?<=>)(\w*-*\w*)(?=\/<)")

    Project=$(zenity --list --width=500 --height=350 --radiolist --title "Select project" --text="Available projects:" --column="" --column="Project" "${projectsArg[@]}")
    if [[ -z $Project ]]; then
        message="No project chosen"
        show_error "$message"
        displayEndInstallation "$Group" "Finished - Error" "$message"
        exit 1
    fi

    # Retrieve original value from alias if it exists
    for key in "${!projectAliases[@]}"; do
        if [[ "$Project" == "${projectAliases[$key]}" ]]; then
            Project="$key"
        fi
    done
fi

if [[ -z $Project ]]; then
    message="No project chosen"
    show_error "$message"
    displayEndInstallation "$Group" "Finished - Error" "$message"
    exit 1
fi

logThis "User chose project $Project" "INFO" false

dep_rul="https://debs.photo-me.eu/installation/dependencies/${Group}/laundry/${Project}/"
displayEndInstallation "dependencies file at ${dep_rul}"

if [[ -z $Operator ]]; then

    # Gather all operators
    operators=$(curl -s ${dep_rul} | grep -Po "(?<=>)(\w*-*\w*)(?=\/<)")

    # Get profile rights for operators
    rightsSectionName="operators"
    operatorsRights=$(cat ./rightsOperators | grep -Poz "(?<=$rightsSectionName:{\n)([\S\s]*)([\S\s]*)(?=})" | tr -d '\0')

    # If rights are set then we need to filter components
    if [[ -n $operatorsRights ]]; then
        rights=$(echo $operatorsRights | grep -Po "(?<=$profile:)([^;]*)(?=;)")
        if [[ -z $rights ]]; then
            message="No rights found in $rightsSectionName for $profile"
            show_error "$message"
            displayEndInstallation "$Group $Project" "Finished - Error" "$message"
            exit 1
        fi
        # filter
        filteredOperators=$(echo $operators | grep -Po "$rights")
        if [[ -z $filteredOperators ]]; then
            message="No filtered Operators found with rights for $profile"
            show_error "$message"
            displayEndInstallation "$Group $Project" "Finished - Error" "$message"
            exit 1
        fi
        operators=$filteredOperators
    fi

    # Gather all operators
    i=0
    operatorsArg=""
    for line in $operators; do
        prefix="FALSE "
        if [[ $i == 0 ]]; then
            prefix="TRUE "
        fi
        
        operatorsArg="${operatorsArg}${prefix}${line} "
        i=$((i+1))
    done < <(curl -s https://debs.photo-me.eu/installation/dependencies/${Group}/laundry/${Project}/ | grep -Po "(?<=>)(\w*-*\w*)(?=\/<)")

    Operator=$(zenity --list --width=500 --height=350 --radiolist --title "Select operator" --text="Available operators:" --column="" --column="Operator" ${operatorsArg})
fi

if [[ -z $Operator ]]; then
    message="No operator chosen"
    show_error "$message"
    displayEndInstallation "$Group $Project" "Finished - Error" "$message"
    exit 1
fi

logThis "User chose operator $Operator" "INFO" false

dep_rul="https://debs.photo-me.eu/installation/dependencies/${Group}/laundry/${Project}/${Operator}/"
LogAndOutputToZenity "dependencies file at ${dep_rul}"

if [[ -z $Component ]]; then

    # Gather all components
    components=$(curl -s ${dep_rul} | grep -Po "(?<=>)(\w*-*\w*)(?=\/<)")

    # Get profile rights for components
    rightsSectionNameComponents="components"
    componentsRights=$(cat ./rightsComponents | grep -Poz "(?<=$rightsSectionNameComponents:{\n)([\S\s]*)([\S\s]*)(?=})" | tr -d '\0')
    # If rights are set then we need to filter components
    if [[ -n $componentsRights ]]; then
        rights=$(echo $componentsRights | grep -Po "(?<=$profile:)([^;]*)(?=;)")
        displayEndInstallation "rights: $rights"
        if [[ -z $rights ]]; then
            message="No rights found in $rightsSectionNameComponents for $profile"
            show_error "$message"
            displayEndInstallation "$Group $Project $Operator" "Finished - Error" "$message"
            exit 1
        fi
        # filter
        filteredComponents=$(echo $components | grep -Po "$rights")
        displayEndInstallation "filtered component 1: $Group $Project $Operator: components: $components and rights: $rights + filteredComponents: $filteredComponents"
        if [[ -z $filteredComponents ]]; then
            message="No component found with rights for $profile"
            show_error "$message"
            displayEndInstallation "$Group $Project $Operator" "Finished - Error" "$message"
            exit 1
        fi
        components=$filteredComponents
    fi

    i=0
    componentsArg=""
    for line in $components; do
        prefix="FALSE "
        if [[ $i == 0 ]]; then
            prefix="TRUE "
        fi
        
        componentsArg="${componentsArg}${prefix}${line} "
        i=$((i+1))
    done

    Component=$(zenity --list --width=500 --height=350 --radiolist --title "Select component" --text="Available components:" --column="" --column="Component" ${componentsArg})
fi

if [[ -z $Component ]]; then
    message="No component chosen"
    show_error "$message"
    displayEndInstallation "$Group $Project $Operator" "Finished - Error" "$message"
    exit 1
fi

logThis "User chose component $Component" "INFO" false

if [[ -z $MachineName ]]; then
    MachineName=$(zenity --entry --title "Machine name" --text "Please enter machine name:")
fi

if [[ -z $MachineName ]]; then
    message="No machine name"
    show_error "$message"
    displayEndInstallation "$Group $Project $Operator $Component" "Finished - Error" "$message"
    exit 1
fi


if [[ -z $Repository ]]; then
    Repository="${Operator}-${Component}"
fi

LogAndOutputToZenity "Start installation from following repository: $Repository..."

if [[ -n /etc/apt/trusted.gpg.d/kis-aptly.gpg ]] ; then
    LogAndOutputToZenity "Adding aptly key..."
    curl -s https://debs.photo-me.eu/aptly_repo_signing.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/kis-aptly.gpg add 2>&1 >> $logFile
fi

aptsource="/etc/apt/sources.list.d/kis-app.list"

if [[ -f ${aptsource} ]] ; then
    LogAndOutputToZenity "Deleting old apt source at ${aptsource}..."
    sudo rm -f ${aptsource}
fi

if [[ -n ${aptsource} ]] ; then
    LogAndOutputToZenity "Creating new apt source at ${aptsource}..."
    echo "deb [arch=armhf] https://debs.photo-me.eu/${Repository} ${Operator} ${Component}" > ./kis-app.list
    sudo cp ./kis-app.list ${aptsource}
    rm ./kis-app.list
fi

LogAndOutputToZenity "Download dependencies file..."

dependencies_url="https://debs.photo-me.eu/installation/dependencies/${Group}/laundry/${Project}/${Operator}/${Component}/aptly_dependencies"

sudo mkdir -p /kis/app

# Delete dependencies.old backup because a new one has been downloaded
sudo rm -f /kis/app/dependencies
sudo rm -f /kis/app/dependencies.url

LogAndOutputToZenity "Writing /kis/app/dependencies.url with ${dependencies_url}"
echo "${dependencies_url}" | sudo tee -a /kis/app/dependencies.url

LogAndOutputToZenity "Apt update..."

sudo apt-get update 2>&1 >> $logFile

if [[ $skipInstall != true ]]; then
    LogAndOutputToZenity "Installing all packages from dependencies url..."
    source ./install-dependencies.sh
    result=$?
else
    LogAndOutputToZenity "Skipping install"
    result=0
fi

logFolder="${HOME}/installation"
logFile="${logFolder}/installation.log"

if [[ $result != 0 ]]; then

    message="Error in install-dependencies"
    LogAndOutputToZenity "$message"
    displayEndInstallation "$Group $Project $Operator $Component $MachineName" "Finished - Error" "$message"
    exit 1
fi

if [[ $skipInstall != true ]]; then
    LogAndOutputToZenity "Changing machine name to ${MachineName}..."

    sudo apt-get install -y -qq jq 2>&1 >> $logFile

    echo "$(jq --arg MachineName "$MachineName" '.MachineName = $MachineName' /kis/static/configuration/global.json)" > /kis/static/configuration/global.json

    LogAndOutputToZenity "Restoring backed up stats (if any)..."

    backupFolder="/kis/backup"

    if [[ -d $backupFolder ]]; then
        sudo mv -n ${backupFolder}/*.json /kis/static/statistics/
        sudo mv -n ${backupFolder}/counter.txt /kis/static/configuration/services/payment/counter.txt
    fi

    if [[ ! -f /kis/static/configuration/services/payment/counter.txt ]]; then
        touch /kis/static/configuration/services/payment/counter.txt
    fi

    # We need to create them here as dpkg packages should not create anything in user folders at install (see Debian guidelines)
    LogAndOutputToZenity "Creating desktop shortcuts..."

    ln -s /kis/app/services/receipt/ticketZ.desktop ${HOME}/Desktop/ticketZ.desktop

    ln -s /kis/app/services/payment/payment-tool.desktop ${HOME}/Desktop/payment-tool.desktop
    ln -s /kis/app/services/payment/verifone-configurator.desktop ${HOME}/Desktop/verifone-configurator.desktop
    ln -s /kis/app/services/payment/castle-configurator.desktop ${HOME}/Desktop/castle-configurator.desktop

    ln -s /kis/app/services/hardware/hardwareApp.desktop ${HOME}/Desktop/hardwareApp.desktop

    ln -s /kis/app/services/maintenance-configurator/maintenance-configurator.desktop ${HOME}/Desktop/maintenance-configurator.desktop

    ln -s /kis/app/launcher/kis-launcher.desktop ${HOME}/Desktop/kis-launcher.desktop
    ln -s /kis/app/supervisor/kis-supervisor.desktop ${HOME}/Desktop/kis-supervisor.desktop

    rilevaFolder="${HOME}/Rileva"
    if [[ -d $rilevaFolder ]]; then
    LogAndOutputToZenity "Creating rileva shortcuts on desktop..."
    ln -s ${HOME}/Rileva/Configuration/rileva-configuration.desktop ${HOME}/Desktop/rileva-configuration.desktop
    fi

    LogAndOutputToZenity "Configuring TeamViewer log level..."

    tvConfPath="/etc/teamviewer/global.conf"
    # Escape brackets opening for grep
    logLevelVar="\[int32] Log_Level"
    logLevelValue="200"
    logLevel="${logLevelVar} = $logLevelValue"
    isLogLevelSet=$(sudo cat "$tvConfPath" | grep "${logLevelVar}")

    if [[ -z $isLogLevelSet ]];then
        echo "${logLevel}" | sudo tee -a "${tvConfPath}"
        logThis "TeamViewer log level set to $logLevelValue" "DEBUG" false
    fi

    LogAndOutputToZenity "Deleting installation files..."
    sudo rm -rf /kis/app/docker

    kistoolFolder="/kis/tools"
    
    # Add execution right for this folder (technicien need this right to execute script in this folder)
    if [[ -d $kistoolFolder ]]; then
        sudo chmod -R a+x ${kistoolFolder}
    fi

    LogAndOutputToZenity "Installation finished"

    LogAndOutputToZenity "Running configurator..."
    # Open configurator on payment page direclty
    (/kis/app/services/maintenance-configurator/maintenance-configurator.sh payment) &
fi

echo 100

displayEndInstallation "$Group $Project $Operator $Component $MachineName" "Finished - Success" ""
return 0