#!/bin/bash

# Globals
serviceName="babel.licensing"
serviceEndpointUrl="http://*:5005"
serviceDisplayName="Babel Licensing"
serviceDescription="Babel licensing and reporting network services."

# Check prerequisites at the beginning of the script
function check_prerequisites {
    echo "Checking prerequisites..."
    
    # Check if running as root
    if [ "$EUID" -ne 0 ]; then
        echo "This script requires root privileges. Please run as root."
        exit 1
    else
        echo "Script is running with root privileges."
    fi
    
    # Check if MariaDB CLI command is installed
    if ! command -v mysql &> /dev/null; then
        echo "MariaDB CLI command is not installed or not in the system PATH. Please install MariaDB and ensure the CLI command is in the system PATH."
        exit 1
    else
        echo "MariaDB CLI command is installed."
    fi
    
    # Check if dotnet is installed
    if ! command -v dotnet &> /dev/null; then
        echo "dotnet is not installed or not in the system PATH. Please install dotnet and ensure the CLI command is in the system PATH."
        exit 1
    else
        echo "dotnet is installed at $dotnetPath."
        
        # Check if dotnet version is at least 6
        local dotnetVersion=$(dotnet --version | cut -d'.' -f1)
        if [ "$dotnetVersion" -lt 6 ]; then
            echo "Installed dotnet version is less than 6. Please install dotnet version 6 or higher."
            exit 1
        else
            echo "Installed dotnet version is $dotnetVersion, which is sufficient."
        fi
    fi

    # Check if jq is installed
    if ! command -v jq &> /dev/null; then
        echo "jq is not installed. Please install jq to proceed."
        exit 1
    else
        echo "jq is installed."
    fi
}

function get_random_password {
    local length="$1"
    echo $(tr -dc 'a-zA-Z0-9!@#$%^&*()+[]{}|;:,.<>?' </dev/urandom | fold -w "$length" | head -n 1)
}

function get_directory_path {
    read -p "Please enter the install directory path: " directoryPath
    echo $directoryPath
}

function get_dotnet_path {
    local dotnetPath=$(which dotnet)
    
    if [ -z "$dotnetPath" ]; then
        echo "dotnet is not installed or not in the system PATH. Please install dotnet and ensure the CLI command is in the system PATH."
        exit 1
    fi
    
    echo $dotnetPath
}

function get_installer_path {
    local zipFiles=$(find . -maxdepth 1 -name 'babel_service*.zip')
    
    if [ -z "$zipFiles" ]; then
        read -p "No babel service zip file found in the script directory. Enter the full path of the Babel Licensing Service ZIP file: " zipFilePath
    else
        local zipFilePath=$(echo $zipFiles | head -n1)
    fi
    
    echo $zipFilePath
}

function get_license_file {
    local licenseFiles=$(find . -maxdepth 1 -name '*.licenses')
    
    if [ -z "$licenseFiles" ]; then
        read -p "No license file found in the script directory. Enter the full path of the Babel Licensing Service license file: " licenseFilePath
    else
        local licenseFilePath=$(echo $licenseFiles | head -n1)
    fi
    
    echo $licenseFilePath
}

function install_service {
    # Get babel service install zip
    local zipFilePath=$(get_installer_path)
    
    # Ask the user for the directory to extract the ZIP file
    local extractDirectory=$(get_directory_path)
    
    # Check if the directory exists, if not create it
    if [ ! -d "$extractDirectory" ]; then
        mkdir -p "$extractDirectory"
    fi

    # Extract the ZIP file to the chosen directory
    unzip -o "$zipFilePath" -d "$extractDirectory" > /dev/null 2>&1
    
    # Set owner
    chown www-data:www-data -R "$extractDirectory"
    
    # Copy the license file to the target folder
    local licenseFilePath=$(get_license_file)
    cp "$licenseFilePath" "$extractDirectory/babel.licenses"
    
    # Create the database
    read -s -p "Enter MySQL 'root' database password: " rootPassword
    echo ""
    read -s -p "Enter the password for the 'babel' database user: " databasePassword
    echo ""
    
    # Run SQL commands to create the database, user, and grant privileges
    local commands="
CREATE DATABASE IF NOT EXISTS licenses;
CREATE USER IF NOT EXISTS 'babel'@'localhost' IDENTIFIED BY '$databasePassword';
GRANT ALL PRIVILEGES ON licenses.* TO 'babel'@'localhost';
FLUSH PRIVILEGES;
"
    echo "$commands" | mysql -u root -p"$rootPassword"
    
    # Edit appsettings.json to fix the connection string
    local appSettingsPath="$extractDirectory/appsettings.json"
    
    jq --arg password "$databasePassword" \
       --arg extractDirectory "$extractDirectory" \
       --arg serviceEndpointUrl "$serviceEndpointUrl" \
       --arg signingKey "$(get_random_password 16)" \
    '.Serilog.WriteTo[1].Args.path = "\($extractDirectory)/log.txt" |
     .Kestrel.Endpoints.gRPC.Url = $serviceEndpointUrl |
     .Application.SigningKey = $signingKey |
     .Database.Provider = "MySQL" |
     .ConnectionStrings.MySQL = "Server=127.0.0.1;User=babel;Password=\($password);Database=licenses"' \
    $appSettingsPath > "$extractDirectory/tmp.json" && mv "$extractDirectory/tmp.json" $appSettingsPath
    
    # Install the Babel.Licensing.Service as a Systemd Service
    local servicePath="$extractDirectory/Babel.Licensing.Service.dll"
    local dotnetPath=$(get_dotnet_path)

    echo "[Unit]
Description=$serviceDescription
After=network.target

[Service]
ExecStart=$dotnetPath $servicePath
WorkingDirectory=$extractDirectory
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=babel-licensing-svc
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/$serviceName.service
    
    systemctl enable $serviceName
    systemctl start $serviceName
    
    echo "Installation completed successfully!"
}

function uninstall_service {
    # Check if the service exists
    if systemctl --all --type service --full | grep -q "$serviceName.service"; then
        # Stop and remove the service
        systemctl stop $serviceName
        systemctl disable $serviceName
        rm /etc/systemd/system/$serviceName.service
        systemctl daemon-reload
        echo "Service uninstalled successfully!"
    else
        echo "Service is not installed!"
    fi
}

# Check prerequisites
check_prerequisites

# Present the user with a menu
while true; do
    echo "Babel Licensing Service"
    echo "This script will install and configure the Babel Licensing Service"
    echo "Please choose an option:"
    echo "1. Install Service"
    echo "2. Get Service Status"
    echo "3. Start Service"
    echo "4. Stop Service"
    echo "5. Uninstall Service"
    echo "6. Exit"
    echo -n "> "
    
    read -r userChoice
    
    case $userChoice in
        1) install_service ;;
        2) systemctl status $serviceName ;;
        3) systemctl start $serviceName ;;
        4) systemctl stop $serviceName ;;
        5) uninstall_service ;;
        6) break ;;
        *) echo "Invalid choice, please choose again!" ;;
    esac
done
