#!/bin/bash

# This script is free software and is released under the terms of the
# GNU General Public License, Version 3 (GPLv3).
# You are free to use, modify, and redistribute this software in accordance
# with the terms of the GPLv3.
# THIS SOFTWARE IS PROVIDED >>AS IS<<, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE
# USE OR OTHER DEALINGS IN THE SOFTWARE.
# Use of this script is entirely at your own risk.

###########################################################################
# roetest_linux_install                                                   #
###########################################################################
# Markus Schnackenberg                                                    #
# Created      2026-07-01                                                 #
# Last updated 2026-07-01                                                 #
# Version      1.31                                                       #
# Language     English                                                    #
###########################################################################
# This script will (semi-)automatically install the RoeTest software on   #
# a linux machine under wine and will ensure to make all the configu-     #
# ration steps to get the RoeTest hardware functioning with the RoeTest   #
# software in a linux maschine.                                           #
###########################################################################
#                                                                         #
# Linux distros supported:                                                #
#-------------------------                                                #
# Linux Mint, Version 21.x            not tested yet                      #
# Linux Mint, Version 22.x            tested 2026-07-01                   #
# Debian    , Version 12              tested 2026-07-01                   #
# Debian    , Version 13              tested 2026-07-01                   #
# Ubuntu    , Version 22.04           tested 2026-07-01                   #
# Ubuntu    , Version 24.04           tested 2026-07-01                   #
# Ubuntu    , Version 25.04           tested 2026-07-01                   #
# Ubuntu    , Version 25.10           tested 2026-07-01                   #
# Ubuntu    , Version 26.04           tested 2026-07-01                   #
#                                                                         #
###########################################################################

# >> Define version of this script
script_version="1.31"

# >> Path to this script which was started
SCRIPT_FILE="$(realpath "${BASH_SOURCE[0]}")"

# >> Catch actual user in variable
username="${SUDO_USER:-$USER}"

# Depress waring messages from wine in Script
export WINEDEBUG=-all

# >> Define colors for message displaying
red="\033[1;31m"
green="\033[1;32m"
purple="\033[1;35m"
blue="\033[1;34m"
nc="\033[0m"

# >> Find Linux distro and save to variable
distro=$(cat /etc/os-release | grep '^ID=' | sed 's/^ID=//')
version=$(cat /etc/os-release | grep '^VERSION_ID="' | sed 's/^VERSION_ID="//; s/"$//')

# >> Define repository based on Linux Distro and version as well as release information for install
# >> refer to https://gitlab.winehq.org/wine/wine/-/wikis/Debian-Ubuntu
release_install="not released"
run_i386="yes"
# Linux Mint 22
if [[ ("$distro" == "linuxmint" && "$version" =~ ^22(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
# Ubuntu 24.04, noble
elif [[ ("$distro" == "ubuntu" && "$version" =~ ^24\.04(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
# Linux Mint 21
elif [[ "$distro" == "linuxmint" && "$version" =~ ^21(\..*)?$ ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
# Ubuntu 22.04, jammy
elif [[ ("$distro" == "ubuntu" && "$version" =~ ^22\.04(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
# Ubuntu 25.04, plucky
elif [[ ("$distro" == "ubuntu" && "$version" =~ ^25\.04(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/plucky/winehq-plucky.sources"
    release_install="released"
    path_software="/media"
    pixels="168"
# Ubuntu 25.10, questing
elif [[ ("$distro" == "ubuntu" && "$version" =~ ^25\.10(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/questing/winehq-questing.sources"
    release_install="released"
    path_software="/media"
    run_i386="no"
    pixels="168"
# Ubuntu 26.04, resolute
elif [[ ("$distro" == "ubuntu" && "$version" =~ ^26\.04(\..*)?$) ]]; then
    repository_url="https://dl.winehq.org/wine-builds/ubuntu/dists/resolute/winehq-resolute.sources"
    release_install="released"
    path_software="/run"
    run_i386="no"
    pixels="168"
# Debian 13, trixie
elif [[ "$distro" == "debian" && "$version" =~ ^13(\..*)?$ ]]; then
    repository_url="https://dl.winehq.org/wine-builds/debian/dists/trixie/winehq-trixie.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
# Debian 12, bookworm
elif [[ "$distro" == "debian" && "$version" =~ ^12(\..*)?$ ]]; then
    repository_url="https://dl.winehq.org/wine-builds/debian/dists/bookworm/winehq-bookworm.sources"
    release_install="released"
    path_software="/media"
    pixels="98"
fi

# >> Check arguments once script is called
case "$1" in
    -h|--help)
        echo "Installation and configuration of RoeTest on Linux"
        echo
        echo "Root privileges are required for some operations."
        echo "This script semi-automatically installs and configures the RoeTest software on Linux."
        echo "It installs and configures Wine, installs the RoeTest software, and creates all"
        echo "necessary configuration files to get the RoeTest software and hardware running"
        echo "on a Linux system."
        echo
        echo "Created by M. Schnackenberg, July 2026"
        echo
        echo "Usage: roetest_linux_install [OPTIONS]"
        echo
        echo "Options:"
        echo "  -h, --help      Display this help and exit"
        echo "  -v, --version   Output version information and exit"
        exit 0
        ;;
    -v|--version)
        echo "RoeTest on Linux - Installation and Configuration Script"
        echo "Version $script_version"
        exit 0
        ;;
esac

# >> Display Linux distro information and check if script is supporting the Linux distro
echo "Installation and configuration of RoeTest Software and Hardware on Linux"
echo "Root privileges are required for some operations!"
echo "You will be required to enter your sudo password"
echo ""
echo "Linux distro is: $distro"
echo "Version is:      $version"
echo "User:            $username"
if [[ "$release_install" != "released" ]]; then
   echo -e "${red}Linux Distro $distro with version $version is not supported by script, exiting${nc}"
   exit 2
fi

# >> User intercation: insert installation media and press any key to start
echo ""
echo -e "${blue}Please insert USB-Stick or CD-ROM with RoeTest Software you got from Helmut Weigl${nc}"
echo -e "${blue}Especially in Debian open the USB drive or CD-ROM once a time in a file manager${nc}"
echo -e "${blue}that the media is mounted correctly${nc}"
echo -e "${blue}Press any key to start the installation and configuration process...${nc}"
read -n 1 -s

# >> Update package repositories (root privileges required)
echo ""
echo "Updating package respositories"
sudo apt update &>/dev/null

# >> In case Distro is Debian, check if contrib is in sources (needed for winetricks installation)
if [[ "$distro" == "debian" ]]; then
  if [ -f /etc/apt/sources.list.d/debian.sources ]; then
      sudo sed -i '/^Components:/ {
          / contrib /! s/$/ contrib/
      }' /etc/apt/sources.list.d/debian.sources
  elif [ -f /etc/apt/sources.list ]; then
      sudo sed -i '/^deb / {
          / contrib /! s/$/ contrib/
      }' /etc/apt/sources.list
  fi
fi

# >> Adding 32-bit architecture (root privileges required)
if [[ "$run_i386" == "yes" ]]; then
   echo ""
   echo "Adding 32-bit archtitecture (sudo required)"
   sudo dpkg --add-architecture i386
fi

# >> Adding winehq key to local reyring (root privileges required)
echo ""
echo "Adding winehq respository key to local keyring (sudo required)"
if [[ -f /etc/apt/keyrings/winehq-archive.key ]]; then
    echo -e "${purple}Skip adding key to keyring${nc} - Key still existing"
else
    wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor -o /etc/apt/keyrings/winehq-archive.key -
fi

# >> Adding repository winehq to package sources (root privileges required)
echo ""
echo "Adding winehq respository to package sources (sudo required)"
if grep -Rqs "winehq" /etc/apt/sources.list /etc/apt/sources.list.d/; then
    echo -e "${purple}Skip adding winehq to package sources${nc} - Package souce definition already existing"
else
    sudo wget -NP /etc/apt/sources.list.d/ "$repository_url"
fi

# >> Update package repositories (root privileges required)
echo ""
echo "Updating package respositories"
sudo apt update &>/dev/null

# >> Install winehq-stable (root privileges required)
echo ""
if sudo apt show winehq-stable 2>/dev/null | grep "Package: winehq-stable" &>/dev/null
   then
     if sudo apt list --installed winehq-stable 2>/dev/null | grep "winehq-stable" &>/dev/null
       then
         echo -e "${purple}Skip winehq-stable${nc} - already installed"
       else
         echo "Installing winehq-stable"
         sudo apt install --install-recommends winehq-stable -y &>/dev/null
         if [ $? -eq 0 ]
           then
             echo -e "${green}Installation of winehq-stable succesfull${nc}"
           else
             echo -e "${red}Installation of winehq-stable failed, please check!${nc}"
             exit 2
         fi
     fi
   else
     echo -e "${red}Package winehq-stable not in sources of this computer!${nc}"
     exit 2
fi

# >> Install winetricks (root privileges required)
if sudo apt show winetricks 2>/dev/null | grep "Package: winetricks" &>/dev/null
   then
     if sudo apt list --installed winetricks 2>/dev/null | grep "winetricks" &>/dev/null
       then
         echo -e "${purple}Skip winetricks${nc} - already installed"
       else
         echo "Installing winetricks"
         sudo apt install winetricks -y &>/dev/null
         if [ $? -eq 0 ]
           then
             echo -e "${green}Installation of winetricks succesfull${nc}"
           else
             echo -e "${red}Installation of winetricks failed, please check!${nc}"
             exit 2
         fi
     fi
   else
     echo -e "${red}Package winetricks not in sources of this computer!${nc}"
     exit 2
fi

# >> Setting up wine configuration for first startup
echo ""
echo "Setting up wine configuration"
echo -e "${blue}If you will be asked in a GUI window to install MONO Installer please confirm${nc}"
echo -e "${blue}Press any key to continue...${nc}"
read -n 1 -s
wineboot --init

# >> Setting Windows version 10 in wine
echo ""
echo "Setting wine Windows version to Windows 10"
wine reg add "HKCU\\Software\\Wine\\Wine\\Config" /v Version /d win10 /f &>/dev/null

# >> Setting graphics to 168 pixels in wine
echo ""
echo "Setting wine graphics to $pixels dpi"
wine reg add "HKCU\Control Panel\Desktop" /v LogPixels /t REG_DWORD /d "$pixels" /f
wineboot -r

# >> Installing corefonts in wine for better displaying text in wine
echo ""
echo "Installing corefonts for wine"
winetricks -q corefonts &>/dev/null

# >> Search for RoeTest Software (CD-Rom or USB stick)
echo ""
echo "Searching for RoeTest Software"
path=$(find "$path_software" -type d -name "Software" -print -quit 2>/dev/null)
if [[ -n "$path"  ]]; then
   echo -e "${green}Found path $path${nc}"
else
   echo -e "${red}No installation path found - exiting script${nc}"
   exit 2
fi
cd "$path"

# >> Install RoeTest software with wine
echo ""
echo -e "Installing Roetest software - ${blue}please uncheck launch after installation"
echo -e "and follow instructions from Helmut Weigl in the installer GUI"
echo -e "Leave the installation path as given!${nc}"
echo -e "${blue}Press any key to continue...${nc}"
read -n 1 -s
wine setup.exe

# >> Copy folders needed for RoeTest Software to wine installation
cp -r "$path"/backup ~/.wine/drive_c/roetest/
cp -r "$path"/common_data_and_settings ~/.wine/drive_c/roetest/
cp -r "$path"/Fassungen ~/.wine/drive_c/roetest/
cp -r "$path"/Messdaten ~/.wine/drive_c/roetest/
cp -r "$path"/pictures ~/.wine/drive_c/roetest/
cp -r "$path"/Sockel ~/.wine/drive_c/roetest/
cp -r "$path"/Sockel_PinNr ~/.wine/drive_c/roetest/
cp -r "$path"/tubepictures ~/.wine/drive_c/roetest/

# >> Detect RoeTest Hardware while connecting via USB
echo ""
echo -e "${blue}Please turn RoeTest Hardware on and connect it via USB cable to computer"
echo -e "Ensure not connecting any other USB device during operation!${nc}"
while read -r line; do

    # Identify Vendor + Product
    if [[ "$line" =~ idVendor=([^,[:space:]]+).*idProduct=([^,[:space:]]+) ]]; then
        idVendor="${BASH_REMATCH[1]}"
        idProduct="${BASH_REMATCH[2]}"
        echo "Vendor:  $idVendor"
        echo "Product: $idProduct"
    fi

    # Identify SerialNumber
    if [[ "$line" =~ SerialNumber:[[:space:]]*([^[:space:]]+) ]]; then
        SerialNumber="${BASH_REMATCH[1]}"
        echo "Serial: $SerialNumber"
        echo -e "${green}RoeTest device identified${nc}"
        break
    fi
done < <(sudo dmesg -W)

# >> Create ALIAS for RoeTest Hardware (USB)
echo ""
echo "Creating udev rule for alias /dev/roetest in /etc/udev/rules.d/99-usb.rules"
if grep -Fq "ATTRS{serial}==\"$SerialNumber\"" /etc/udev/rules.d/99-usb.rules 2>/dev/null; then
    echo -e "${purple}Skip creating udev rule${nc} - for device with SerialNumber $SerialNumber a udev rule already  existing"
else
   sudo tee /etc/udev/rules.d/99-usb.rules > /dev/null <<EOF
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idProduct}=="$idProduct", ATTRS{idVendor}=="$idVendor", ATTRS{serial}=="$SerialNumber", SYMLINK+="roetest", MODE="0660", GROUP="dialout"
EOF

   echo "Reload udev rules"
   sudo udevadm trigger
fi

# >> Linking /dev/roetest to COM 1 in wine
echo ""
echo "Linking COM1 in wine to /dev/roetest"
rm ~/.wine/dosdevices/com1
ln -s /dev/roetest ~/.wine/dosdevices/com1

# >> Configure USB interface in registry editor in wine
echo ""
echo "Configuring USB interface in registry editor in wine"
wine reg add "HKLM\Software\Wine\Ports" /v COM1 /t REG_SZ /d "/dev/roetest" /f &>/dev/null

# >> User must be member of GROUP dialout
echo ""
echo "Check if User $username is belonging to group dialout"
if id -nG "$username" | grep -qw "dialout"; then
    echo -e "${green}User belongs to group dialout${nc}"
else
    echo "User not belonging to group dialout."
    echo "Adding $username to group dialout (sudo required)"
    sudo usermod -aG dialout "$username"

    # Preparing reboot and reboot
    echo -e "${green}Installation finished!"
    echo -e "${blue}Reboot necessary - you can launch Roetest after reboot"
    echo -e "Press any key to reboot...${nc}"
    read -n 1 -s
    sudo reboot
    exit 0
fi

# >> User information installation and configuration finished
echo -e "${green}Installation finished!"
echo ""
echo -e "${nc}Starting RoeTest..."
wine start "C:\roetest\RoeTest.exe"
exit 0
