#!/bin/bash
clear

set -e  # Exit immediately if a command exits with a non-zero status

catch_exits() {  # function to clean up install files if script is aborted
    echo "Removing Robo-Tank Installation Files           ...takes less than 1 minute"
    sudo rm -r /boot/robotank/ &> /dev/null
    sudo rm -r "Robo-Tank_v6_6.zip" &> /dev/null
    exit 0
    printf "\n$(basename $0): exiting\n" 1>&2
    rm -rf $DIR
    exit 1
}

trap catch_exits 1 2 3 15 20  # run clean up if script is aborted

# Define color variables
cyan='\033[0;36m'
NC='\033[0m' # No Color
bold=$(tput bold)
normal=$(tput sgr0)

startup() {
    echo ""
    echo ""
    echo ""
    echo ""
    echo "This script will automate the installation process for Robo-Tank but does require attending."
    echo ""
    echo ""
    echo "This script does the following"
    echo "    * updates Raspberry Pi Operating System"
    echo "    * enables time sync"
    echo "    * installs phpMyAdmin"
    echo "    * installs Apache2"
    echo "    * Integrate PHP with Apache"
    echo "    * installs MySQL"
    echo "    * installs Robo-Tank"
    echo "    * installs MySQL library"
    # echo "    * installs wiringPi library"
    echo "    * installs libwebsockets library"
    echo "    * installs libcurl library"
    echo "    * installs libquickmail library"
    echo "    * installs Robo-Tank service on Raspberry Pi"
    echo "    * removes Robo-Tank installation files"
    echo "    * generates website address to access Robo-Tank"
    echo "    * expands file system on microSD card"
    echo ""
    echo ""
    echo ""
    echo "Press enter to continue or press ${bold}Ctrl + C${normal} to abort"
    read input
    echo ""
    echo ""
    echo -e "${cyan}________________________________________________________________________________________${NC}"
    echo ""
    echo ""
    echo ""
    echo ""

    # check if sudo is used
    if [ "$(id -u)" != 0 ]; then
        echo ""
        echo ""
        echo "You need to run this script with ${bold}sudo${normal} at the beginning of the command"
        echo ""
        echo ""
        echo ""
        echo ""
        exit 1
    fi
}

# Function to update the Raspberry Pi OS
update_os() {
    echo "Updating Raspberry Pi OS..."
    sudo apt-get update && sudo apt-get upgrade -y
}

update_config_txt() {
    echo ""
    # # Retrieve the OS version codename
    codename=$(grep VERSION_CODENAME /etc/os-release | cut -d '=' -f 2)

    # Check the codename and run code accordingly
    if [[ "$codename" == "bookworm" ]]; then
        echo "Running code for Bookworm..."
        echo "Updating /boot/firmware/config.txt..."
        
        # Backup the original config.txt file if not already backed up
        if [ ! -f /boot/config.org ]; then
            sudo cp /boot/firmware/config.txt /boot/config.org
        fi

        # Use a temporary file to build the new config.txt
        temp_config=$(mktemp)
        sudo cp /boot/firmware/config.txt "$temp_config"

    else
        echo "Running code for other OS variant..."
        echo "Updating /boot/config.txt..."

        # Backup the original config.txt file if not already backed up
        if [ ! -f /boot/config.org ]; then
            sudo cp /boot/config.txt /boot/config.org
        fi

        # Use a temporary file to build the new config.txt
        temp_config=$(mktemp)
        sudo cp /boot/config.txt "$temp_config"
    fi

    # Ensure the following lines are uncommented/added
    sudo sed -i 's/^#dtparam=i2c_arm=on/dtparam=i2c_arm=on/' "$temp_config"

    if ! grep -q '^dtparam=i2c_vc=off' "$temp_config"; then  # disable the ID EEPROM function so we can use ID_SD* (P27) and ID_SC* (P28) pins
        echo 'dtparam=i2c_vc=off' | sudo tee -a "$temp_config" > /dev/null
    fi
    if ! grep -q '^dtparam=i2c_arm_baudrate=10000' "$temp_config"; then
        echo 'dtparam=i2c_arm_baudrate=10000' | sudo tee -a "$temp_config" > /dev/null
    fi
    if ! grep -q '^dtoverlay=i2c-rtc,ds1307' "$temp_config"; then
        echo 'dtoverlay=i2c-rtc,ds1307' | sudo tee -a "$temp_config" > /dev/null
    fi
    if ! grep -q '^dtoverlay=pwm-2chan' "$temp_config"; then
        echo 'dtoverlay=pwm-2chan' | sudo tee -a "$temp_config" > /dev/null
    fi

    # Remove any existing instances of the w1-gpio lines
    sudo sed -i '/^dtoverlay=w1-gpio/d' "$temp_config"
    sudo sed -i '/^#dtoverlay=w1-gpio/d' "$temp_config"

    # Define the lines to add
    w1_gpio_lines=(
        'dtoverlay=w1-gpio,gpiopin=4'
        'dtoverlay=w1-gpio,gpiopin=22'
        '#dtoverlay=w1-gpio,gpiopin=14'
        '#dtoverlay=w1-gpio,gpiopin=15'
        '#dtoverlay=w1-gpio,gpiopin=17'
        '#dtoverlay=w1-gpio,gpiopin=18'
        '#dtoverlay=w1-gpio,gpiopin=27'
        '#dtoverlay=w1-gpio,gpiopin=23'
    )

    # Add the required lines at the end
    for line in "${w1_gpio_lines[@]}"; do
        echo "${line}" | sudo tee -a "$temp_config" > /dev/null
    done

    if [[ "$codename" == "bookworm" ]]; then
        # Overwrite the original config.txt with the modified one
        sudo cp "$temp_config" /boot/firmware/config.txt
    else
        # Overwrite the original config.txt with the modified one
        sudo cp "$temp_config" /boot/config.txt
    fi

    sudo rm "$temp_config"

    echo "config.txt updated successfully."
    echo ""
}

update_config_txt2() {
    # File to update
    if [[ "$codename" == "bookworm" ]]; then
        config_file="/boot/firmware/config.txt"
    else
        config_file="/boot/config.txt"
    fi

    # Comment out specific lines if they exist
    lines_to_comment=(
        'dtoverlay=w1-gpio,gpiopin=14'
        'dtoverlay=w1-gpio,gpiopin=15'
        'dtoverlay=w1-gpio,gpiopin=17'
        'dtoverlay=w1-gpio,gpiopin=18'
        'dtoverlay=w1-gpio,gpiopin=27'
        'dtoverlay=w1-gpio,gpiopin=23'
    )

    for line in "${lines_to_comment[@]}"; do
        if grep -q "^${line}" "$config_file"; then
            # echo "Commenting out ${line}"
            sudo sed -i "s/^${line}/#${line}/" "$config_file"
        fi
    done
}

configure_raspi() {
    echo "Configuring Raspberry Pi settings..."

    sudo raspi-config nonint do_onewire 0  # Enable 1-wire
    sudo raspi-config nonint do_spi 1      # Disable SPI
    sudo apt install -y i2c-tools
    
    # change session.gc_maxlifetime variable in php.ini so user will not be logged out
    
    if [ -d "/etc/php/7.4/apache2/" ]; then
    PHP_INI_PATH="/etc/php/7.4/apache2/php.ini"  # Path to php.ini file    
    NEW_SESSION_LIFETIME="session.gc_maxlifetime = 31536000"  # New value for session.gc_maxlifetime

        cp "$PHP_INI_PATH" "$PHP_INI_PATH.bak"  # Backup the original php.ini file
        sed -i '/session\.gc_maxlifetime/d' "$PHP_INI_PATH"  # Delete existing session.gc_maxlifetime lines
        echo "$NEW_SESSION_LIFETIME" >> "$PHP_INI_PATH"  # Append new session.gc_maxlifetime value to php.ini file
    else
        echo "Directory /etc/php/7.4/apache2/ not found. Aborting."
    fi

    if [ -d "/etc/php/8.2/apache2/" ]; then
        PHP_INI_PATH="/etc/php/8.2/apache2/php.ini"  # Path to php.ini file    
        NEW_SESSION_LIFETIME="session.gc_maxlifetime = 31536000"  # New value for session.gc_maxlifetime

        cp "$PHP_INI_PATH" "$PHP_INI_PATH.bak"  # Backup the original php.ini file
        sed -i '/session\.gc_maxlifetime/d' "$PHP_INI_PATH"  # Delete existing session.gc_maxlifetime lines
        echo "$NEW_SESSION_LIFETIME" >> "$PHP_INI_PATH"  # Append new session.gc_maxlifetime value to php.ini file
    else
        echo "Directory /etc/php/8.2/apache2/ not found. Aborting."
    fi

    echo "Raspberry Pi configuration updated successfully."
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

enable_i2c_modules() {
    echo "Enabling I2C modules..."

    MODULES_FILE=/etc/modules
    if ! grep -q 'i2c-bcm2708' $MODULES_FILE; then
        echo 'i2c-bcm2708' | sudo tee -a $MODULES_FILE > /dev/null
    fi
    if ! grep -q 'i2c-dev' $MODULES_FILE; then
        echo 'i2c-dev' | sudo tee -a $MODULES_FILE > /dev/null
    fi

    echo "I2C modules enabled successfully."
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

setup_hardware_clock() {
    echo "Setting up hardware clock..."

    sudo apt -y remove fake-hwclock
    sudo update-rc.d -f fake-hwclock remove

    HW_CLOCK_SET_FILE=/lib/udev/hwclock-set
    if ! grep -q '#if \[ -e /run/systemd/system' $HW_CLOCK_SET_FILE; then
        sudo sed -i 's+if \[ -e /run/systemd/system+#if \[ -e /run/systemd/system+g' $HW_CLOCK_SET_FILE
        sudo sed -i '0,/    exit/{s/    exit/#    exit/}' $HW_CLOCK_SET_FILE
        sudo sed -i '0,/fi/{s/fi/#fi/}' $HW_CLOCK_SET_FILE
    fi

    echo "Hardware clock setup completed successfully."
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

config_one_wire() {
    echo "Configuring One Wire..."

    sudo cp /boot/robotank/install/w1.conf /etc/modprobe.d/w1.conf &> /dev/null
    sudo cp /boot/robotank/install/modules.conf /etc/modules.conf &> /dev/null

    echo "One wire configured successfully."
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to enable time synchronization
enable_time_sync() {
    echo "Enabling time synchronization..."
    sudo timedatectl set-ntp true
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to install phpMyAdmin
install_phpmyadmin() {
    echo "Preconfiguring phpMyAdmin for non-interactive installation..."
    echo "mysql-server mysql-server/root_password password robotank" | sudo debconf-set-selections
    echo "mysql-server mysql-server/root_password_again password robotank" | sudo debconf-set-selections
    echo 'phpmyadmin phpmyadmin/dbconfig-install boolean false' | sudo debconf-set-selections
    echo 'phpmyadmin phpmyadmin/app-password-confirm password robotank' | sudo debconf-set-selections
    echo 'phpmyadmin phpmyadmin/mysql/admin-pass password robotank' | sudo debconf-set-selections
    echo 'phpmyadmin phpmyadmin/mysql/app-pass password robotank' | sudo debconf-set-selections
    echo 'phpmyadmin phpmyadmin/reconfigure-webserver multiselect apache2' | sudo debconf-set-selections

    echo "Installing phpMyAdmin..."
    sudo apt-get install -y phpmyadmin php-mbstring

    # Validate phpMyAdmin installation
    if ! dpkg -l phpmyadmin &> /dev/null; then
        echo "ERROR: phpMyAdmin installation failed."
        exit 1
    fi
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to integrate PHP with Apache
install_php() {
    echo "Integrating PHP with Apache..."
    sudo apt-get install php libapache2-mod-php -y
    sudo systemctl restart apache2

    # Validate PHP installation
    if ! dpkg -l php &> /dev/null; then
        echo "ERROR: PHP installation failed."
        exit 1
    fi
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to install install_MySQL
install_MySQL() {
    echo "Installing install_MySQL..."
    sudo apt-get install mariadb-server php-mysql -y

    ssh_username=$(whoami)

    set +e
    sudo usermod -a -G www-data "$ssh_username"
    sudo chown -R -f www-data:www-data /var/www/html
    sudo mysql --user=root < /boot/robotank/install/create_database.sql  # create database user
    set -e
    
    sudo apt-get install libmariadb-dev-compat libmariadb-dev -y
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to install wiringPi library
# install_wiringPi() {
#     echo "Installing wiringPi library..."
#     sudo dpkg -i /boot/robotank/install/wiring-pi/wiringpi-latest.deb

#     # Validate wiringPi installation
#     if ! dpkg -l | grep -q wiringpi; then
#         echo "ERROR: wiringPi installation failed."
#         exit 1
#     fi
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
#     echo ""
# }

# Function to install libwebsockets library
install_libwebsockets() {
    echo "Installing libwebsockets library..."
    sudo apt-get install libwebsockets-dev -y

    # Validate libwebsockets library installation
    if ! dpkg -l libwebsockets-dev &> /dev/null; then
        echo "ERROR: libwebsockets library installation failed."
        exit 1
    fi
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to install libcurl library
install_libcurl() {
    echo "Installing libcurl library..."
    sudo apt-get install libcurl4-openssl-dev -y

    # Validate libcurl library installation
    if ! dpkg -l libcurl4-openssl-dev &> /dev/null; then
        echo "ERROR: libcurl library installation failed."
        exit 1
    fi
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}
 
# Function to install libquickmail library
install_libquickmail() {
    echo "Installing libquickmail..."

    # Check if libquickmail is already installed
    if ldconfig -p | grep -q libquickmail; then
        echo "libquickmail is already installed."
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        echo ""
        return 0
    fi

    cd /boot/robotank/install/libquickmail/  # Change directory

    max_attempts=5
    attempt=1

    while [ $attempt -le $max_attempts ]; do
        echo "Attempt $attempt of $max_attempts..."

        # Temporarily disable exit on error
        set +e
        
        # Run the installation commands
        sudo chmod +x configure
        sudo ./configure
        sudo make
        sudo make install
        sudo sh -c "echo '/usr/local/lib' >> /etc/ld.so.conf"
        sudo ldconfig

        # Re-enable exit on error
        set -e

        # Validate libquickmail installation
        if ldconfig -p | grep -q libquickmail; then
            echo "libquickmail installed successfully."
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            echo ""
            return 0
        else
            echo "ERROR: libquickmail installation attempt $attempt failed."
        fi

        attempt=$((attempt + 1))
        if [ $attempt -le $max_attempts ]; then
            echo "Retrying in 5 seconds..."
            sleep 5
        fi
    done

    echo "ERROR: libquickmail installation failed after $max_attempts attempts."
    return 1
}

# Function to install Robo-Tank
install_robotank() {
    echo "Installing Robo-Tank..."
    sudo cp -rf /boot/robotank/* /var/www/html
    # sudo cp -r /boot/robotank/* /var/www/html
    sudo chown -R pi:www-data /var/www/html/
    sudo chmod -R 770 /var/www/html/
    sudo mysql --user=root --password=robotank < /boot/robotank/install/robotank_database.sql

    # Assuming you have a repository or a specific way to install Robo-Tank
    # Replace the following line with the actual installation commands
    # echo "Please replace this with the actual Robo-Tank installation commands."
    g++ -o /var/www/html/cpp/robotank /var/www/html/cpp/robotank.cpp `mysql_config --cflags --libs` -lpthread -lquickmail -lcurl

    SERVICE_FILE="/boot/robotank/install/robotank.service"
    SYSTEMD_PATH="/etc/systemd/system/robotank.service"

    if [ ! -f "$SERVICE_FILE" ]; then
        echo "ERROR: $SERVICE_FILE not found!"
        exit 1
    fi

    sudo cp "$SERVICE_FILE" "$SYSTEMD_PATH"

    # Ensure the Robo-Tank service file has the correct permissions
    sudo chmod 644 "$SYSTEMD_PATH"

    # Enable and start the Robo-Tank service
    sudo systemctl daemon-reload
    sudo systemctl enable robotank.service
    sudo systemctl start robotank.service
    
    if [ -f /var/www/html/index.html ]; then
        sudo rm /var/www/html/index.html
    fi

    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
}

# Function to expand the file system
expand_filesystem() {
    echo "Expanding the file system..."
    sudo raspi-config --expand-rootfs

    # Validate the file system expansion
    if [ $? -eq 0 ]; then
        echo "File system expanded successfully."
    else
        echo "ERROR: File system expansion failed."
        exit 1
    fi
}

# Main script execution
main() {
    startup
    update_os
    enable_time_sync
    install_phpmyadmin
    install_php
    install_MySQL
    # install_wiringPi
    install_libwebsockets
    install_libcurl
    install_libquickmail
    install_robotank
    update_config_txt
    configure_raspi
    enable_i2c_modules
    setup_hardware_clock
    config_one_wire
    update_config_txt2
    
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo -e "${cyan}________________________________________________________________________________________${NC}"
    echo ""
    echo ""
    echo ""
    echo ""
    echo ""
    echo "You have successfully installed Robo-Tank, you can now press ${bold}ENTER${normal}"
    echo "on your keyboard to restart your Raspberry Pi."
    echo ""
    echo "After the Raspberry Pi restarts open a web browser from any device on your local "
    echo "network and type one of the links below. The first link is the IP address of the"
    echo "Raspberry Pi, the 2nd link is the hostname you added during the installation. Write"
    echo "these down or create a bookmark in your browser. Note it is possible your network"
    echo "changes the IP address for the Raspberry Pi and the link no longer works, this is"
    echo "why we setup a hostname as this will never change."
    echo ""
    ip= hostname -I | awk '{ print "http://" $1 }'
    echo "${bold}http://$new_hostname${normal}"
    echo ""
    echo ""

    echo "The default login for Robo-Tank is as follows."
    echo ""
    echo "Username = ${bold}Robo-Tank${normal}"
    echo "Password = ${bold}Robo-Tank${normal}"
    echo ""
    echo ""
    echo "Have a great day!"
    echo ""
    echo ""
    echo ""
    echo "Press ${bold}ENTER${normal} on your keyboard to restart the Raspberry Pi."
    echo ""
    echo ""
    echo ""
    read -p "Press ENTER to continue..." input

    expand_filesystem

    echo "Removing Robo-Tank Installation Files           ...takes less than 1 minute"
    # Schedule the reboot to happen in 2 seconds
    (sleep 2 && sudo reboot) &
    echo "Rebooting Controller is 2 seconds"

    sudo rm -r /boot/robotank/ &> /dev/null
    sudo rm -r "Robo-Tank_v6_6.zip" &> /dev/null
}

main
