#!/bin/bash

set -e

declare -A INSTALL_STATUS

print_summary() {
  echo ""
  echo "========== INSTALLATION SUMMARY =========="

  for key in "${!INSTALL_STATUS[@]}"; do
    printf "%-10s : %s\n" "$key" "${INSTALL_STATUS[$key]}"
  done

  echo "=========================================="
}

trap 'summary; print_summary' EXIT

# Installation functions

install_docker_version() {
  DOCKER_SHORT_VERSION="$1"

  if [[ -z "$DOCKER_SHORT_VERSION" ]]; then
    echo "[ERROR] No Docker version provided."
    echo "Usage: install_docker_version <version>, e.g., install_docker_version 28.1.1"
    INSTALL_STATUS["Docker"]="Failed"
    return 1
  fi

  REPO_URL="https://download.docker.com/linux"

  # Detect OS and codename
  source /etc/os-release
  OS_ID="${ID,,}"
  CODENAME="${VERSION_CODENAME:-$(lsb_release -cs)}"

  if [[ "$OS_ID" != "ubuntu" && "$OS_ID" != "debian" ]]; then
    echo "[ERROR] Unsupported OS: $OS_ID"
    INSTALL_STATUS["Docker"]="Failed"
    return 1
  fi

  echo "[INFO] Detected OS: $OS_ID ($CODENAME)"
  echo "[INFO] Requested Docker version: $DOCKER_SHORT_VERSION"

  # Install prerequisites
  sudo apt update
  sudo apt install -y ca-certificates curl gnupg lsb-release

  # Add Docker GPG key
  sudo mkdir -p /etc/apt/keyrings
  curl -fsSL $REPO_URL/$OS_ID/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

  # Add Docker repo
  echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
    $REPO_URL/$OS_ID $CODENAME stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

  sudo apt update

  # Dynamically find the correct full version string
  DOCKER_PKG_VERSION=$(apt-cache madison docker-ce | grep "$DOCKER_SHORT_VERSION" | head -n1 | awk '{print $3}')

  if [[ -z "$DOCKER_PKG_VERSION" ]]; then
    echo "[ERROR] Docker version $DOCKER_SHORT_VERSION not found in APT repository."
    echo "[INFO] Available versions:"
    apt-cache madison docker-ce
    INSTALL_STATUS["Docker"]="Failed"
    return 1
  fi

  echo "[INFO] Installing Docker version: $DOCKER_PKG_VERSION"

  # Install Docker
  sudo apt install -y \
    docker-ce="$DOCKER_PKG_VERSION" \
    docker-ce-cli="$DOCKER_PKG_VERSION" \
    containerd.io

  # Enable + start service
  sudo systemctl enable docker
  sudo systemctl start docker

  # Verify
  docker --version

  echo "[SUCCESS] Docker $DOCKER_SHORT_VERSION installed successfully."
}

install_python_binary_version() {
    sudo apt update -y
    sudo apt install software-properties-common -y
    sudo add-apt-repository -y ppa:deadsnakes/ppa
    sudo apt update -y
    sudo apt install python3.9 -y
    sudo apt install python3.9-distutils -y
    $SUDO wget https://bootstrap.pypa.io/get-pip.py
    export IIP_PYTHON=$(which python3.9)
    $SUDO $IIP_PYTHON get-pip.py
    echo "Python 3.9 installation completed."
}

install_python_compile_sources_version() {
    PYTHON_SHORT_VERSION="$1"
    sudo apt update -y
    sudo apt install -y build-essential libssl-dev zlib1g-dev \
        libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
        libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev \
        libgdbm-dev liblzma-dev uuid-dev
    $SUDO mkdir -p $CurPath/PyPaths/sources/python3.9
    cd $CurPath/PyPaths/sources/python3.9
    $SUDO wget https://www.python.org/ftp/python/${PYTHON_SHORT_VERSION}/Python-${PYTHON_SHORT_VERSION}.tgz
    $SUDO tar xzf Python-${PYTHON_SHORT_VERSION}.tgz
    cd Python-3.9.21
    $SUDO ./configure --prefix=$CurPath/PyPaths/python3.9 --enable-optimizations --with-ensurepip=install
    $SUDO make -j$(nproc)
    $SUDO make altinstall
    echo "Python $PYTHON_SHORT_VERSION installation completed."
}

install_confirm() {
  local name="$1"
  local yn="$2"
  local version="$3"

  case "$yn" in
    [Yy])
      echo "Installing $name $version"
      ;;
    [Ee])
      echo "$name is already installed with accepted version, $name $version"
      ;;
  esac
}

check_installed() {
  local name="$1"
  local expected="$2"
  local required="$3"

  local installed
  installed=$(get_version "$name")

  if [[ "$required" == "y" || "$required" == "Y" ]]; then
    if [[ -z "$installed" ]]; then
      INSTALL_STATUS["$name"]="Failed"
    elif [[ "$installed" == "$expected" ]]; then
      INSTALL_STATUS["$name"]="Installed ($installed)"
    else
      INSTALL_STATUS["$name"]="Version Mismatch (Installed: $installed, Expected: $expected)"
    fi
  elif [[ "$required" == "e" || "$required" == "E" ]]; then
      INSTALL_STATUS["$name"]="Already Exist"
  fi
}

get_version() {
  local tool="$1"

  case "$tool" in
    Java)
      java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+' || true
      ;;

    Maven)
      mvn -version 2>&1 | grep "Apache Maven" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true
      ;;

    Python)
      $IIP_PYTHON --version 2>&1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true
      ;;

    Docker)
      docker --version | grep -oP '[[:digit:]]{1,2}\.[[:digit:]]{1,2}\.[[:digit:]]{1,2}' | head -1
      ;;

    Node.js)
      node --version 2>&1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true
      ;;

    Angular)
      ng version 2>&1 | grep 'Angular CLI:' | awk '{print $3}' || true
      ;;

    *)
      echo "unknown"
      return 1
      ;;
  esac
}

summary() {
    check_installed "Java" "$OktJavaVersion" "$Javayn"
    check_installed "Maven" "$OktMvnVersion" "$Mavenyn"
    check_installed "Python" "$OktPythonVersion" "$Pythonyn"
    check_installed "Docker" "$OktDockerVersion" "$Dockeryn"
    check_installed "Node.js" "$OktNodeVersion" "$Nodeyn"
    check_installed "Angular" "$OktAngularVersion" "$Angularyn"
}

install_completed() {
  localOktDepsOnly="$1"

  if [ -n "$localOktDepsOnly" ] && [ "$localOktDepsOnly" == "DepsOnly" ]; then
    echo "Only the dependencies of the Platform was installed (Not the full Platform)"
    echo "Run 'source ~/.bashrc' or open a new terminal to apply environment variables."
  else
    echo "The following commands were created in Platform\Install\gen:"
    echo "- broker/broker.sh starts the configured communication broker (cd needed)"
    echo "- platform.sh starts the central platform services"
    echo "- mgtUi.sh starts the Angular-based management UI (Angular required, http://localhost:4200)"
    echo "- per device that shall execute services, either ECS-Runtime and service manager or the combined"
    echo "  combined ECS-Runtime-Servicemanager must be executed"
    echo "  - ecs.sh starts the ECS-Runtime"
    echo "  - serviceMgr.sh starts the service manager"
    echo "  - ecsServiceMgr.sh starts the combined ECS-Runtime/Service-Manager"
    echo "- cli.sh starts the platform command line interface"
    echo "In individual shells, start at least the broker, the central services and the device services, then" 
    echo "the included application (cli.sh deploy artifacts/deployment.yaml). On a permanent installation, only" 
    echo "accessing the UI or the CLI is needed."
    echo "Please consult the installation overview for more information."
    echo "Run 'source ~/.bashrc' or open a new terminal to apply environment variables."
  fi

}

# End of installation function

# Start of platform installation

OktJavaVersion=17
OktMvnVersion=3.9.7
OktPythonVersion=3.9.21
OktDockerVersion=28.1.1
OktNodeVersion=22.14.0
OktNpmVersion=10.9.2
OktAngularVersion=19.2.5

RunSudo=false
SUDO=""

while [[ "$#" -gt 0 ]]; do
  case $1 in
    --OktDepsOnly)
      if [[ "$2" == "DepsOnly" ]]; then
        OktDepsOnly="$2"
      else
        echo "Error: --OktDepsOnly must be 'DepsOnly'"
        exit 1
      fi
      shift
      ;;
    --RunSudo)
      if [[ "$2" == "true" || "$2" == "false" ]]; then
        RunSudo="$2"
      else
        echo "Error: --RunSudo must be 'true' or 'false'"
        exit 1
      fi
      shift
      ;;
    *) echo "Unknown parameter: $1"; 
       echo "Allowed argument are "
       echo "--OktDepsOnly DepsOnly: Installing Only the dependencies of the Platform (Not the full Platform)."
       echo "--RunSudo true/false: Prefix all commands with sudo (default: false)."
       exit 1 ;;
  esac
  shift
done

# set sudo variable
if [[ "$RunSudo" == "true" ]]; then
  SUDO="sudo"
fi

echo "Oktoflow platform installation (Linux)"
echo "Installing prerequisites Java $OktJavaVersion, Maven version $OktMvnVersion, and Python version $OktPythonVersion"
echo "This action will set and use Environment Variables"
read -p "Do you want to install the prerequisites (skip only if already installed)? (y/n) " yn
if [ $yn == "y" ] || [ $yn == "Y" ]; then 
    
    mkdir -p Setup && cd Setup
    
    # Check current Java version 
    
    if [ -x "$(command -v java -version)" ]; then
        JAVA_VERSION=$(java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+' || true)
        if [ $JAVA_VERSION -lt $OktJavaVersion ]; then
            echo "The Java version you have is less than the minimum requirement Java $OktJavaVersion for the IIP-Ecosphere platform"
            echo "Your Java version is "$JAVA_VERSION
            while true; do
                read -p "Do you want to install Java $OktJavaVersion - you should have at least Java $OktJavaVersion? - You can't skip this step; if you skip it the installation will end. (y/n) " Javayn
                case $Javayn in
                    [Yy]* ) break;;
                    [Nn]* ) exit;;
                    * ) echo "Please answer y or n.";;
                esac
            done
        else
            Javayn="E";
        fi    
    else
        Javayn="Y";
    fi
    
    # Check current Maven version
    
    if [ -x "$(command -v mvn -version)" ]; then
        MVN_VERSION=$(mvn -version | grep "Apache Maven" | grep -oP '[[:digit:]]\.[[:digit:]]\.[[:digit:]]')
        if ! [ $MVN_VERSION == $OktMvnVersion ]; then
            echo "You have Maven version $MVN_VERSION, it is recommended to have version $OktMvnVersion"
            while true; do
                read -p "Do you want to install Maven $OktMvnVersion and replace Maven default to $OktMvnVersion? - You might skip this step (y/n) " Mavenyn
                case $Mavenyn in
                    [Yy]* ) break;;
                    [Nn]* ) break;;
                    * ) echo "Please answer y or n.";;
                esac
            done
        else
            Mavenyn="E";
        fi
    else
        Mavenyn="Y";
    fi
    
    # Check current Python version

    echo "Please enter the path for your runnable python3.9 (or newer) or your Python the virtual environment (in case of using one). If Python does not exist then please enter (n). "
    read -p "Your runnable python3.9 or your Python the virtual environment: " PythonPath
    while [ -z "$PythonPath" ]; do
        echo "Please enter the path for your runnable python3.9 (or newer) or your Python the virtual environment (in case of using one). If Python does not exist then please enter (n). "
        read -p "Your runnable python3.9 or your Python the virtual environment: " PythonPath
    done

    if [[ "$PythonPath" != "N" && "$PythonPath" != "n" ]]; then
        while true; do
            read -p "You have Python installed in $PythonPath, correct (y/n)? " CheckPath
            case $CheckPath in
                [Yy]* ) break;;
                [Nn]* ) read -p "please enter the correct path for runnable python3.9 or your Python the virtual environment: " PythonPath;;
                * ) echo "Please answer y or n.";;
            esac
        done
    fi

    if [ -x "$(command -v $PythonPath --version)" ]; then
        PYTHON_VERSION=$($PythonPath --version | grep -oP '[[:digit:]]{1,2}\.[[:digit:]]{1,2}\.[[:digit:]]{1,2}')
        if ! [ $PYTHON_VERSION == $OktPythonVersion ]; then
            echo "You have Python version $PYTHON_VERSION, it is recommended to have version $OktPythonVersion"
            while true; do
                read -p "Do you want to install Python $OktPythonVersion? - You might skip this step (y/n) " Pythonyn
                case $Pythonyn in
                    [Yy]* ) break;;
                    [Nn]* ) break;;
                    * ) echo "Please answer y or n.";;
                esac
            done

            if [[ "$Pythonyn" == "Y" || "$Pythonyn" == "y" ]]; then
                echo "Please choose: (a) Take the most recent 3.9.x (untested), (b) Download source and compile 3.9.21 (It takes more time)."
                while true; do
                    read -p "Please choose how to install python (a/b): " PythonInstallModeab
                    os_info=$(grep "^PRETTY_NAME=" /etc/os-release | cut -d= -f2- | tr -d '"')
                    if [[ "$os_info" == *"Debian GNU/Linux"* && ( "$PythonInstallModeab" == "A" || "$PythonInstallModeab" == "a" ) ]]; then
                        echo "Detected Debian: $os_info. Debian does not support method (a) to install 3.9.x"
                    else
                        case $PythonInstallModeab in
                            [Aa]* ) break;;
                            [Bb]* ) break;;
                            * ) echo "Please answer a or b.";;
                        esac
                    fi
                done
            fi
        else
            Pythonyn="E";
        fi
    else
        Pythonyn="Y";
        echo "Please choose: (a) Take the most recent 3.9.x (untested), (b) Download source and compile 3.9.21 (It takes more time)."
        while true; do
            read -p "Please choose how to install python (a/b): " PythonInstallModeab
            os_info=$(grep "^PRETTY_NAME=" /etc/os-release | cut -d= -f2- | tr -d '"')
            if [[ "$os_info" == *"Debian GNU/Linux"* && ( "$PythonInstallModeab" == "A" || "$PythonInstallModeab" == "a" ) ]]; then
                echo "Detected Debian: $os_info. Debian does not support method (a) to install 3.9.x"
            else
                case $PythonInstallModeab in
                    [Aa]* ) break;;
                    [Bb]* ) break;;
                    * ) echo "Please answer a or b.";;
                esac
            fi
        done
    fi

    if [ -z "$OktDepsOnly" ]; then
        while true; do
            read -p "Do you want to install Docker $OktDockerVersion to use containers in the platform? - You might skip this step (y/n) " InstallDockeryn
            case $InstallDockeryn in
                [Yy]* ) break;;
                [Nn]* ) break;;
                * ) echo "Please answer y or n.";;
            esac
        done

        if [ $InstallDockeryn == "y" ] || [ $InstallDockeryn == "Y" ]; then 
            # Check current Docker version 

            if [ -x "$(command -v docker --version)" ]; then
                DOCKER_VERSION=$(docker --version | grep -oP '[[:digit:]]{1,2}\.[[:digit:]]{1,2}\.[[:digit:]]{1,2}' | head -1)
                if ! [ $DOCKER_VERSION == $OktDockerVersion ]; then
                    echo "You have Docker version $DOCKER_VERSION, it is recommended to have version $OktDockerVersion"
                    while true; do
                        read -p "Do you want to install Docker $OktDockerVersion and replace Docker default to $OktDockerVersion? - You might skip this step (y/n) " Dockeryn
                        case $Dockeryn in
                            [Yy]* ) break;;
                            [Nn]* ) break;;
                            * ) echo "Please answer y or n.";;
                        esac
                    done
                else
                    Dockeryn="E";
                fi
            else
                Dockeryn="Y";
            fi
        else
            Dockeryn="N";
        fi

        # Check Docker Private Registry

        while true; do
            read -p "Do you want to start Docker Private Registry (You should have Docker installed, be carefull it will restart Docker service) for the platform? - You might skip this step (y/n) " Registryyn
            case $Registryyn in
                [Yy]* ) break;;
                [Nn]* ) break;;
                * ) echo "Please answer y or n.";;
            esac
        done

        # Check Node.js 22.x and Angular 19

        while true; do
            echo "To use the management UI for the platform you should have angular version $OktAngularVersion installed (with npm and Node.js)"
            read -p "Do you want to install Node.js version 22.x (latest), angular version $OktAngularVersion, and npm package manager for the JavaScript? - You might skip this step (y/n) " Nodeyn 
            case $Nodeyn in
                [Yy]* ) break;;
                [Nn]* ) break;;
                * ) echo "Please answer y or n.";;
            esac
        done   

        if [[ "$Nodeyn" == "Y" || "$Nodeyn" == "y" ]]; then
            if [ -x "$(command -v node --version)" ]; then
                NODE_VERSION=$(node --version | grep -oP '[[:digit:]]{1,2}\.[[:digit:]]{1,2}\.[[:digit:]]{1,2}' | head -1)
                if [[ "$NODE_VERSION" == "$OktNodeVersion" ]]; then
                    Nodeyn="E";
                elif [[ "$(printf '%s\n' "$NODE_VERSION" "$OktNodeVersion" | sort -V | head -n1)" == "$version_a" ]] && [[ "$version_a" != "$version_b" ]]; then
                    echo "You have Node.js version $NODE_VERSION, it is recommended to have at least version $OktNodeVersion"
                    while true; do
                        read -p "Do you want to install Node.js 22.x (latest) version? - You might skip this step (y/n) " Nodeyn
                        case $Nodeyn in
                            [Yy]* ) break;;
                            [Nn]* ) break;;
                            * ) echo "Please answer y or n.";;
                        esac
                    done
                else
                    echo "You have Node.js version $NODE_VERSION, it is newer than $OktNodeVersion. It shall work"
                    Nodeyn="E";
                fi
            else
                Nodeyn="Y";
            fi

            if [ -x "$(command -v ng --version)" ]; then
               ANG_VERSION=$(ng version | grep 'Angular CLI:' | awk '{print $3}')
               if ! [[ "$ANG_VERSION" == "$OktAngularVersion" ]]; then
                  echo "You have Angular version $ANG_VERSION, it is recommended to have version $OktAngularVersion"
                  while true; do
                      read -p "Do you want to install Angular $OktAngularVersion? - You might skip this step (y/n) " Angularyn
                      case $Angularyn in
                          [Yy]* ) break;;
                          [Nn]* ) break;;
                          * ) echo "Please answer y or n.";;
                      esac
                  done
               else
                   Angularyn="E";
               fi
            else
                Angularyn="Y";
            fi
        fi
    elif [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        Dockeryn="N";
        Nodeyn="N";
        Angularyn="N";
        Registryyn="N";
    fi

    install_confirm "Java" "$Javayn" "$OktJavaVersion"
    install_confirm "Maven" "$Mavenyn" "$OktMvnVersion"
    install_confirm "Python" "$Pythonyn" "$OktPythonVersion"
    install_confirm "Docker" "$Dockeryn" "$OktDockerVersion"
    install_confirm "Node.js" "$Nodeyn" "$OktNodeVersion"
    install_confirm "Angular" "$Angularyn" "$OktAngularVersion"
    if [[ "$Registryyn" == "Y" || "$Registryyn" == "y" ]]; then
        echo "Starting Docker Private Registry"
    fi

    if [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        echo "Installing Only the dependencies of the Platform (Not the full Platform)"
    else
        echo "Installing the full version of the Platform"
    fi

    echo "Note: Installing prerequisites in this script requires administrator privileges!"
    read -p "Press Enter to start the installation..."

    # Install Java version 17
    
    sudo apt-get update
    sudo apt install unzip -y
    sudo apt install jq -y
    
    if ! [ -x "$(command -v java -version)" ]; then
        sudo apt install openjdk-17-jdk-headless -y
    else
        case $Javayn in
            [Yy]* ) sudo apt install openjdk-17-jdk-headless -y; break;;
            [Nn]* ) exit;;
        esac
    fi
    
    # Install Maven version 3.9.7
    
    if ! [ -x "$(command -v mvn -version)" ]; then
        $SUDO wget https://archive.apache.org/dist/maven/maven-3/3.9.7/binaries/apache-maven-3.9.7-bin.tar.gz
        $SUDO tar xzpvf apache-maven-3.9.7-bin.tar.gz
    
        sudo ln -s $PWD/apache-maven-3.9.7/bin/mvn /usr/bin/mvn
    else
        case $Mavenyn in
            [Yy]* ) $SUDO wget https://archive.apache.org/dist/maven/maven-3/3.9.7/binaries/apache-maven-3.9.7-bin.tar.gz;
                    $SUDO tar xzpvf apache-maven-3.9.7-bin.tar.gz;
                    sudo ln -sf $PWD/apache-maven-3.9.7/bin/mvn /usr/bin/mvn;;
            [Nn]* ) echo "";;
        esac
    fi
    
    # Install Python version 3.9
    
    if [[ "$PythonInstallModeab" == "A" || "$PythonInstallModeab" == "a" ]]; then
        if ! [ -x "$(command -v $PythonPath --version)" ]; then
            install_python_binary_version
            export IIP_PYTHON=$(which python3.9)
            $SUDO $IIP_PYTHON -m pip install pyflakes
        else
            case $Pythonyn in
                [Yy]* ) install_python_binary_version;
                        export IIP_PYTHON=$(which python3.9);
                        $SUDO $IIP_PYTHON -m pip install pyflakes;;
                [Nn]* ) echo "";;
            esac
        fi
        echo "export IIP_PYTHON=$(which python3.9)" >> ~/.bashrc
    elif [[ "$PythonInstallModeab" == "B" || "$PythonInstallModeab" == "b" ]]; then
        CurPath=$PWD
        if ! [ -x "$(command -v $PythonPath --version)" ]; then
            install_python_compile_sources_version $OktPythonVersion
            export IIP_PYTHON=$CurPath/PyPaths/python3.9/bin/python3.9
            $SUDO $IIP_PYTHON -m pip install pyflakes
        else
            case $Pythonyn in
                [Yy]* ) install_python_compile_sources_version $OktPythonVersion;
                        export IIP_PYTHON=$CurPath/PyPaths/python3.9/bin/python3.9;
                        $SUDO $IIP_PYTHON -m pip install pyflakes;;
                [Nn]* ) echo "";;
            esac
        fi
        echo "export IIP_PYTHON=$CurPath/PyPaths/python3.9/bin/python3.9" >> ~/.bashrc
        cd $CurPath
    elif [ -n "$PythonPath" ]; then
        export IIP_PYTHON=$PythonPath;
        echo "export IIP_PYTHON=$PythonPath" >> ~/.bashrc
    fi
    
    # Install Docker version 20.10.7

    case $Dockeryn in
        [Yy]* ) install_docker_version $OktDockerVersion;
                sudo usermod -aG docker $USER;;
        [Nn]* ) echo "";;
    esac

    # Install Node.js version 22.x.0 and angular version 19
    
    case $Nodeyn in
        [Yy]* ) sudo apt update;
                sudo apt install -y curl gnupg;
                $SUDO curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -;
                sudo apt install -y nodejs;;
        [Nn]* ) echo "";;
    esac

    case $Angularyn in
        [Yy]* ) sudo npm install -g @angular/cli@19.2.5;;
        [Nn]* ) echo "";;
    esac
    
    sudo apt install curl -y
    
    localIP=$(hostname -I | cut -d ' ' -f1)

    cd ..
    
    cd platformDependencies/
    $IIP_PYTHON -m pip install -r requirements.txt
    cd ..
            
    sed -i 's/147.172.178.145/'$localIP'/g' src/main/easy/TechnicalSetup.ivml
    
    # Run Docker Private Registry
    
    generationLineNumber=$(cat src/main/easy/TechnicalSetup.ivml | grep -n "generation setup" | cut -d ' ' -f1 | sed 's/:/ /g')
    ((generationLineNumber=generationLineNumber-1))

cat >daemon.json <<EOF
{
  "insecure-registries" : ["$localIP:5001"]
}
EOF
                     
    case $Registryyn in
        [Yy]* ) $SUDO sed -i $generationLineNumber' i \ \ \ \ };' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ \ \ \ \ registry = "'$localIP':5001"' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ containerManager = DockerContainerManager {' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ ' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ // ---------- Registry ------------' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ ' src/main/easy/TechnicalSetup.ivml;
                
                sudo mv daemon.json /etc/docker/;
                sudo systemctl restart docker;
                sudo docker  run -d \
                     --restart=always \
                     --name registry \
                     -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
                     -p 5001:5001 \
                     registry:2;;
        [Nn]* ) sudo rm daemon.json;
    esac
    
    if [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        $SUDO mvn -P DepsOnly install
    else
        $SUDO mvn install -Diip.easy.tracing=TOP
    fi

    install_completed "$OktDepsOnly"
    
elif [ $yn == "n" ] || [ $yn == "N" ]; then 

    mkdir -p Setup && cd Setup
    
    echo "Please enter the path for your runnable python3.9 (or newer) or your Python the virtual environment (in case of using one)."
    read -p "Your runnable python3.9 or your Python the virtual environment: " PythonPath
    while [ -z "$PythonPath" ]; do
        echo "Please enter the path for your runnable python3.9 (or newer) or your Python the virtual environment (in case of using one)."
        read -p "Your runnable python3.9 or your Python the virtual environment: " PythonPath
    done

    while true; do
        read -p "You have runnable Python in $PythonPath, correct (y/n)? " CheckPath
        case $CheckPath in
            [Yy]* ) break;;
            [Nn]* ) read -p "please enter the correct path for runnable python3.9 or your Python the virtual environment: " PythonPath;;
            * ) echo "Please answer y or n.";;
        esac
    done
    
    export IIP_PYTHON=$PythonPath
    echo "export IIP_PYTHON=$PythonPath" >> ~/.bashrc

    if [ -z "$OktDepsOnly" ]; then
        # Check Docker Private Registry
        if [ -x "$(command -v docker --version)" ]; then
           while true; do
               read -p "Do you want to start Docker Private Registry (You should have Docker installed, be carefull it will restart Docker service) for the platform? - You might skip this step (y/n) " Registryyn
               case $Registryyn in
                   [Yy]* ) break;;
                   [Nn]* ) break;;
                   * ) echo "Please answer y or n.";;
               esac
           done
        else
           Registryyn=n
        fi

        # Check Node.js 22.x and Angular 19
    
        while true; do
            echo "To use the management UI for the platform you should have angular version $OktAngularVersion installed (with npm and Node.js)"
            read -p "Do you want to install Node.js version 22.x (latest), angular version $OktAngularVersion, and npm package manager for the JavaScript? - You might skip this step (y/n) " Nodeyn 
            case $Nodeyn in
                [Yy]* ) break;;
                [Nn]* ) break;;
                * ) echo "Please answer y or n.";;
            esac
        done   
    
        if [[ "$Nodeyn" == "Y" || "$Nodeyn" == "y" ]]; then
            if [ -x "$(command -v node --version)" ]; then
                NODE_VERSION=$(node --version | grep -oP '[[:digit:]]{1,2}\.[[:digit:]]{1,2}\.[[:digit:]]{1,2}' | head -1)
                if [[ "$NODE_VERSION" == "$OktNodeVersion" ]]; then
                    Nodeyn="E";
                elif [[ "$(printf '%s\n' "$NODE_VERSION" "$OktNodeVersion" | sort -V | head -n1)" == "$version_a" ]] && [[ "$version_a" != "$version_b" ]]; then
                    echo "You have Node.js version $NODE_VERSION, it is recommended to have at least version $OktNodeVersion"
                    while true; do
                        read -p "Do you want to install Node.js 22.x (latest) version? - You might skip this step (y/n) " Nodeyn
                        case $Nodeyn in
                            [Yy]* ) break;;
                            [Nn]* ) break;;
                            * ) echo "Please answer y or n.";;
                        esac
                    done
                else
                    echo "You have Node.js version $NODE_VERSION, it is newer than $OktNodeVersion. It shall work"
                    Nodeyn="E";
                fi
            else
                Nodeyn="Y";
            fi

            if [ -x "$(command -v ng --version)" ]; then
               ANG_VERSION=$(ng version | grep 'Angular CLI:' | awk '{print $3}')
               if ! [[ "$ANG_VERSION" == "$OktAngularVersion" ]]; then
                  echo "You have Angular version $ANG_VERSION, it is recommended to have version $OktAngularVersion"
                  while true; do
                      read -p "Do you want to install Angular $OktAngularVersion? - You might skip this step (y/n) " Angularyn
                      case $Angularyn in
                          [Yy]* ) break;;
                          [Nn]* ) break;;
                          * ) echo "Please answer y or n.";;
                      esac
                  done
               else
                   Angularyn="E";
               fi
            else
                Angularyn="Y";
            fi
        fi

    elif [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        Nodeyn="N";
        Angularyn="N";
        Registryyn="N";
    fi

    install_confirm "Node.js" "$Nodeyn" "$OktNodeVersion"
    install_confirm "Angular" "$Angularyn" "$OktAngularVersion"

    if [[ "$Registryyn" == "Y" || "$Registryyn" == "y" ]]; then
      echo "Starting Docker Private Registry"
    fi

    if [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        echo "Installing Only the dependencies of the Platform (Not the full Platform)"
    else
        echo "Installing the full version of the Platform"
    fi

    echo "Note: Installing prerequisites in this script requires administrator privileges!"
    read -p "Press Enter to start the installation..."

    sudo apt-get update
    sudo apt install unzip -y
    sudo apt install jq -y
   
    # Install Node.js version 22.x.0 and angular version 19
    
    case $Nodeyn in
        [Yy]* ) sudo apt update;
                sudo apt install -y curl gnupg;
                $SUDO curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -;
                sudo apt install -y nodejs;;
        [Nn]* ) echo "";;
    esac

    case $Angularyn in
        [Yy]* ) sudo npm install -g @angular/cli@19.2.5;;
        [Nn]* ) echo "";;
    esac
    
    sudo apt install curl -y
    
    localIP=$(hostname -I | cut -d ' ' -f1)

    cd ..
    
    cd platformDependencies/
    $IIP_PYTHON -m pip install -r requirements.txt
    cd ..

    sed -i 's/147.172.178.145/'$localIP'/g' src/main/easy/TechnicalSetup.ivml

    # Run Docker Private Registry
    
    generationLineNumber=$(cat src/main/easy/TechnicalSetup.ivml | grep -n "generation setup" | cut -d ' ' -f1 | sed 's/:/ /g')
    ((generationLineNumber=generationLineNumber-1))
    
cat >daemon.json <<EOF
{
  "insecure-registries" : ["$localIP:5001"]
}
EOF
                     
    case $Registryyn in
        [Yy]* ) $SUDO sed -i $generationLineNumber' i \ \ \ \ };' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ \ \ \ \ registry = "'$localIP':5001"' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ containerManager = DockerContainerManager {' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ ' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ // ---------- Registry ------------' src/main/easy/TechnicalSetup.ivml;
                $SUDO sed -i $generationLineNumber' i \ \ \ \ ' src/main/easy/TechnicalSetup.ivml;
                
                sudo mv daemon.json /etc/docker/;
                sudo systemctl restart docker;
                sudo docker  run -d \
                     --restart=always \
                     --name registry \
                     -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
                     -p 5001:5001 \
                     registry:2;;
        [Nn]* ) sudo rm daemon.json;;
    esac
    
    if [ -n "$OktDepsOnly" ] && [ "$OktDepsOnly" == "DepsOnly" ]; then
        $SUDO mvn -P DepsOnly install
    else
        $SUDO mvn install -Diip.easy.tracing=TOP
    fi

    install_completed "$OktDepsOnly"
else
    echo "Please answer y or n.";
fi
