#!/bin/bash
# openSUSE migration and upgrade tool utilizes get.opensuse.org product API and openSUSE-repos
# for a cross-distro migration and upgrade to a new versions of point releases.
#
# Copyright 2024 Marcela Maslanova, SUSE LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# For accessing files from git checkout
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# Script dir for git-based execution
POST_MIGRATION_DIR="$SCRIPT_DIR/scripts"

# Migration scripts naming convention:
# Prefix numbers define execution order. Inspired by /etc/grub.d
# Use multiples of 5 or 10 for flexibility, e.g.:
#   05_ for very core low-level tasks,
#   20_ for pulse2pipewire migration,
#   30_ and above for desktop environment or user session tweaks.
#
# Example:
#   20_pulse2pipewire.sh  # Switch PulseAudio to PipeWire early but after core system tasks.

# Fallback to installed location if not found
if [[ ! -d "$POST_MIGRATION_DIR" ]]; then
    POST_MIGRATION_DIR="/usr/share/opensuse-migration-tool/scripts"
fi

# Warn if not found at all
if [[ ! -d "$POST_MIGRATION_DIR" ]]; then
    echo "[ERROR] Post-migration script directory not found: $POST_MIGRATION_DIR"
    exit 1
fi

# Set nice green instead of default blue
if [[ $COLORTERM =~ ^(truecolor|24bit)$ ]]; then
	DIALOGRC="/usr/share/opensuse-migration-tool/dialogrc"
	if [ -f "$SCRIPT_DIR/dialogrc" ]; then
		DIALOGRC="$SCRIPT_DIR/dialogrc"
	fi
	export DIALOGRC
fi

# Ensure required tools are installed
# Double check for zypper in case we're on dnf-based system
REQUIRED_TOOLS=("bc" "jq" "curl" "dialog" "sed" "gawk" "zypper")
for tool in "${REQUIRED_TOOLS[@]}"; do
    if ! command -v "$tool" &>/dev/null; then
        echo "$tool is required but not installed."
        echo "Please run: sudo zypper install ${REQUIRED_TOOLS[*]}"
        exit 1
    fi
done
# Ensure Bash version is 4.0+
if ((BASH_VERSINFO[0] < 4)); then
    echo "This script requires Bash 4.0 or higher." >&2
    exit 1
fi
# Ensure /etc/os-release exists
if [[ ! -f /etc/os-release ]]; then
    echo "File /etc/os-release not found." >&2
    exit 2
fi
# Source OS release info
source /etc/os-release
ARCH=$(uname -i) # x86_64 XXX: check for other arches

# Fetch distribution data from API
API_URL="https://get.opensuse.org/api/v0/distributions.json"
API_DATA=$(curl -s "$API_URL")
if [ $? != 0 ]; then
    echo "Network error: Unable to fetch release data from https://get.opensuse.org/api/v0/distributions.json"
    echo "Ensure that you have working network connectivity and get.opensuse.org is accessible."
    exit 3
fi
DRYRUN=""
TMP_REPO_NAME="tmp-migration-tool-repo" # tmp repo to get sles-release or openSUSE-repos-*
# Initialize MIGRATION_OPTIONS as an empty associative array
declare -A MIGRATION_OPTIONS=()  # human-readable menu label with tips etc
declare -A MIGRATION_RAW=()      # machine-readable versions
declare -A AVAILABLE_TASKS=()

CURRENT_INDEX=1
# Parse command-line arguments
function print_help() {
    echo "Usage: opensuse-migration-tool [--dry-run] [--help]"
    echo "  --dry-run      Show commands without executing them."
    echo "  --help         Show this help message and exit."
    echo
    echo "Report issues: https://github.com/openSUSE/opensuse-migration-tool"
    exit 0
}
while [[ $# -gt 0 ]]; do
    case $1 in
        --dry-run) DRYRUN="echo Would execute: "; shift ;;
        --help) print_help ;;
        *) echo "Unknown option: $1"; exit 1 ;;
    esac
done
export DRYRUN
# Populate migration options
function fetch_versions() {
    local filter="$1"
    local key="$2"
    jq -r ".${key}[] | select(${filter}) | .version" <<<"$API_DATA"
}
function populate_options() {
    local key="$1"
    local current_version="$2"
    local filter="$3"
    local min_version="${4:-}"
    local suffix="${5:-}"
    local versions

    versions=$(fetch_versions "$filter" "$key")
    while IFS= read -r version; do
        if (( $(bc <<<"$current_version < $version") )); then
            if [[ -z "$min_version" ]] || (( $(bc <<<"$version >= $min_version") )); then
                MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE $key $version$suffix"
                MIGRATION_RAW["$CURRENT_INDEX"]="$version"
                ((CURRENT_INDEX++))
            fi
        fi
    done <<<"$versions"
}

# Required x86_64-v2 flags
#required_v2_flags=("cx16" "sse4_1" "sse4_2" "popcnt" "movbe" "xsave")
required_v2_flags=("cx16" "sse4_1" "sse4_2" "popcnt")

# Required x86_64-v3 flags
#required_v3_flags=("cx16" "sse4_1" "sse4_2" "popcnt" "movbe" "xsave" "avx" "avx2" "bmi1" "bmi2" "fma" "abm")

# CPU flags from /proc/cpuinfo
cpu_flags=$(grep -m1 "^flags" /proc/cpuinfo | awk '{for (i=2; i<=NF; i++) print $i}')

# Function to check if all required flags are present
function check_x86_64_v2_support() {
    for flag in "${required_v2_flags[@]}"; do
        if ! grep -qw "$flag" <<< "$cpu_flags"; then
            echo "CPU does not support x86_64-v2 (missing flag: $flag)"
            return 1
        fi
    done
    echo "CPU supports x86_64-v2"
    return 0
}

# Elevated permissions check unless DRYRUN is set
if [ -z "${DRYRUN:-}" ]; then
    if [ "$EUID" -ne 0 ]; then
        exec sudo "$0" "$@"
    fi

	# Requires elevated permissions or test will always fail
	test -w / || { echo "Please run the tool inside 'transactional-update shell' on Immutable systems."; exit 1; }
fi


# System-specific options
if [[ "$NAME" == "openSUSE Leap Micro" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE MicroOS-Slowroll"
    ((CURRENT_INDEX++))
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="MicroOS"
    ((CURRENT_INDEX++))
    # add only Leap versions starting with 16.1
    populate_options "Leap" "$VERSION" '.state!="EOL"' "16.1" " (immutable, replaces Leap Micro)"
    populate_options "LeapMicro" "$VERSION" '.state!="EOL"'
elif [[ "$NAME" == "openSUSE MicroOS" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE MicroOS-Slowroll"
    ((CURRENT_INDEX++))
elif [[ "$NAME" == "openSUSE MicroOS-Slowroll" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="MicroOS"
    ((CURRENT_INDEX++))
elif [[ "$NAME" == "openSUSE Leap" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="SUSE Linux Enterprise $(sed 's/\./ SP/' <<<"$VERSION")"
    ((CURRENT_INDEX++))
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed"
    ((CURRENT_INDEX++))
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed-Slowroll"
    ((CURRENT_INDEX++))
    populate_options "Leap" "$VERSION" '.state!="EOL"'
elif [[ "$NAME" == "openSUSE Tumbleweed" ]]; then
   MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed-Slowroll"
   ((CURRENT_INDEX++))
   echo
elif [[ "$NAME" == "openSUSE Tumbleweed-Slowroll" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed"
    ((CURRENT_INDEX++))
else
    dialog --clear \
    --title "[EXPERIMENTAL] System Migration" \
	--msgbox "\nMigration from $NAME is currently not supported.\n\nPlease report issue at https://github.com/openSUSE/opensuse-migration-tool" \
    10 60
    reset; exit 1;
fi

# Display migration options
if [[ ${#MIGRATION_OPTIONS[@]} -eq 0 ]]; then
    dialog --clear \
    --title "[EXPERIMENTAL] System Migration" \
	--msgbox "\nNo migration options available from $NAME.\n\nPlease report issue at https://github.com/openSUSE/opensuse-migration-tool." \
    10 60
    reset; exit 1
fi
# Prepare dialog items
DIALOG_ITEMS=()
for key in "${!MIGRATION_OPTIONS[@]}"; do
    DIALOG_ITEMS+=("$key" "${MIGRATION_OPTIONS[$key]}")
done
# Display dialog and get choice
CHOICE=$(dialog --clear \
    --title "[EXPERIMENTAL] System Migration" \
    --menu "Select the migration target from $NAME:" \
    20 60 10 \
    "${DIALOG_ITEMS[@]}" \
    2>&1 >/dev/tty) || exit

# Ensure that openSUSE-repos is always installed.
# That handles also the old distribution repository cleanup
$DRYRUN zypper install -y --force-resolution openSUSE-repos
$DRYRUN zypper refresh-services # so we don't see further refresh after disabling repo

# Step: Detect and offer to disable 3rd-party repositories
# This is the #1 reason for failed migration
REPO_LIST=()

# Known 3rd party repos with no $releasever or hardcoded version
exceptions=("google-chrome" )

while IFS="|" read -r num alias name enabled rest; do
    alias=$(echo "$alias" | xargs)  # trim
    name=$(echo "$name" | xargs)
    enabled=$(echo "$enabled" | xargs)

    if [[ "$enabled" == "Yes" ]] && \
       [[ ! "$alias" =~ ^(openSUSE:|NVIDIA:) ]]; then
        if [[ " ${exceptions[*]} " == *" $alias "* ]]; then
            REPO_LIST+=("$alias" "$name" "off")
        else
            REPO_LIST+=("$alias" "$name" "on")
        fi
    fi
done < <(zypper lr -E -d --uri | tail -n +3 | awk -F '|' '{print $1 "|" $2 "|" $3 "|" $4}')

if [[ ${#REPO_LIST[@]} -eq 0 ]]; then
    echo "[INFO] No third-party repositories to disable."
else
    checklist_msg=$(
cat <<EOF
The following enabled repositories are not recognized.
It is strongly recommended to disable them before proceeding with the migration.

Such repositories often have hardcoded URLs or may not yet offer packages
for the target release. This can cause \`zypper dup\` to fail if a repository
is unreachable or incompatible.

You can deselect any repositories you prefer to keep enabled:
EOF
)
    SELECTED_REPOS=$(dialog --clear \
        --title "Disable Third-Party Repositories" \
        --checklist "$checklist_msg" \
        20 80 10 \
        "${REPO_LIST[@]}" \
        2>&1 >/dev/tty)

    for repo in $SELECTED_REPOS; do
        echo "[INFO] Disabling repository: $repo"
        $DRYRUN zypper --non-interactive modifyrepo -d "$repo"
    done
fi

if [[ -n $CHOICE ]]; then
    echo "Selected option: ${MIGRATION_OPTIONS[$CHOICE]}"
    case "${MIGRATION_OPTIONS[$CHOICE]}" in
        *"SUSE Linux Enterprise"*|"SLE")
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"

            SP=$(sed 's/\./-SP/' <<<"$VERSION") # VERSION from /etc/os-release 15.6 -> 15-SP6

            while true; do
                # Capture output and return code
                OUTPUT=$(dialog --clear \
                    --backtitle "SCC - Registration code" \
                    --title "SCC - Registration code" \
                    --form "\nPlease enter valid email and registration code." 25 60 16 \
                    "Email:" 1 1 "" 1 25 25 50 \
                    "Regcode:" 2 1 "" 2 25 25 50 \
                    2>&1 >/dev/tty)
                RETCODE=$?

                #echo "Dialog output: '$OUTPUT'" >&2
                #echo "Return code: $RETCODE" >&2

                # Handle cancel or escape
                if [[ $RETCODE -ne 0 ]]; then
                    dialog --clear \
                        --backtitle "SCC - Registration code" \
                        --title "Operation Cancelled" \
                        --msgbox "You have cancelled the registration process." 10 40
                    reset; exit 1
                fi

                {
                    read -r EMAIL
                    read -r REGCODE 
                } <<< "$OUTPUT"
            
                # Check if both values are entered
                if [[ -n "$EMAIL" && -n "$REGCODE" ]]; then
                    break
                else
                    dialog --clear \
                        --backtitle "SCC - Registration code" \
                        --title "Input Error" \
                        --msgbox "Both email and registration code are required. Please try again." 10 40
                fi
            done

            # This is a dream workflow that doesn't really work. Enable BCI repo and register as SLES with BCI-release
            # Perhaps we can fix it in near future
            #$DRYRUN zypper addrepo -f https://updates.suse.com/SUSE/Products/SLE-BCI/$SP/$ARCH/product/ $TMP_REPO_NAME
            #$DRYRUN zypper install --force-resolution -y suseconnect-ng
            #$DRYRUN zypper install --force-resolution -y unified-installer-release SLE_BCI-release # sles-release is not in BCI

            MAJVER=$(echo $VERSION| awk -F"." '{ print $1 }') # 15
            MINVER=$(echo $VERSION| awk -F"." '{ print $2 }') # 6
            echo $REGCODE
            $DRYRUN zypper install -y suseconnect-ng snapper grub2-snapper-plugin
            # Backup /etc/os-release before release package removal
            echo "Backing up /etc/os-release as /etc/os-release.backup"
            $DRYRUN cp /etc/os-release /etc/os-release.backup
            $DRYRUN rpm -e --nodeps openSUSE-release
            $DRYRUN rpm -e --nodeps openSUSE-repos
            if [ -z "$DRYRUN" ]; then
                cat > /etc/os-release  << EOL
NAME="SLES" 
VERSION="$SP" 
VERSION_ID="$VERSION"
PRETTY_NAME="SUSE Linux Enterprise Server $MAJVER SP$MINVER"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32" 
CPE_NAME="cpe:/o:suse:sles:$MAJVER:sp$MINVER"
DOCUMENTATION_URL="https://documentation.suse.com/"
EOL
            else
                echo "Would write a SLES $SP like /etc/os-release"
            fi

			if [ -f  "$SCRIPT_DIR/SLES.prod" ]; then
				$DRYRUN cp "$SCRIPT_DIR/SLES.prod" /etc/products.d
			else
				$DRYRUN cp /usr/share/opensuse-migration-tool/SLES.prod /etc/products.d
			fi
            $DRYRUN rm -r /etc/products.d/baseproduct
            $DRYRUN ln -s /etc/products.d/SLES.prod /etc/products.d/baseproduct

	        $DRYRUN suseconnect -e  $EMAIL -r $REGCODE 
	        $DRYRUN SUSEConnect -p PackageHub/$VERSION/$ARCH

            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi


            $DRYRUN rpm -e --nodeps branding-openSUSE grub2-branding-openSUSE wallpaper-branding-openSUSE plymouth-branding-openSUSE systemd-presets-branding-openSUSE systemd-presets-branding-MicroOS
	        $DRYRUN zypper remove -y opensuse-welcome # might not be present on text-installations
	        $DRYRUN zypper install -y branding-SLE-15 grub2-branding-SLE wallpaper-branding-SLE-15 plymouth-branding-SLE systemd-presets-branding-SLE
            ;;
        "openSUSE Tumbleweed")
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # https://download.opensuse.org/ports/ # for other arches
            REPOURL="https://download.opensuse.org/tumbleweed/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                REPOURL=https://download.opensuse.org/ports/$ARCH # XXX this will likely work only for aarch64
                if [ "$ARCH" != "aarch64" ]; then 
                    # Let's not messup any systems and make sure this is properly implemented first
                    echo "Unsupported arch '$ARCH'."
                    echo "Please open an issue at https://github.com/openSUSE/opensuse-migration-tool/issues"
                    echo "Make sure to add output of 'uname -i' and content of your /etc/os-release into the ticket."
                    exit 1
                fi
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
            $DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME openSUSE-repos-Tumbleweed # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated
            
            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi

            ;;
        "openSUSE Tumbleweed-Slowroll")
            $DRYRUN echo "Migrating to ${MIGRATION_OPTIONS[$CHOICE]}"
            REPOURL="https://download.opensuse.org/slowroll/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                echo "Unsupported arch '$ARCH' by Slowroll."
                exit 1
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
            $DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME --allow-downgrade openSUSE-repos-Slowroll # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated

            # --allow-downgrade is important in case that you choose Tumblweed -> Slowroll migration
            $DRYRUN zypper dup -y --force-resolution --allow-downgrade --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-downgrade --allow-vendor-change --download in-advance
            fi
            ;;
        *"openSUSE LeapMicro"*)
            # Has to be before Leap*
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # !Important to use MIGRATION_RAW as otherwise MIGRATION_OPTIONS have tips and other decorations
            TARGET_VER=`echo ${MIGRATION_RAW[$CHOICE]} | awk '{ print $NF }'`
            $DRYRUN zypper addrepo -f https://download.opensuse.org/distribution/leap-micro/$TARGET_VER/product/repo/openSUSE-Leap-Micro-$TARGET_VER-$ARCH/ $TMP_REPO_NAME
            $DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME openSUSE-repos-LeapMicro # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated

            $DRYRUN zypper --releasever $TARGET_VER dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper --releasever $TARGET_VER dup --force-resolution --allow-vendor-change --download in-advance 
            fi
            ;;
        *"openSUSE Leap"*)
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            TARGET_VER=`echo ${MIGRATION_RAW[$CHOICE]} | awk '{ print $NF }'`
            if [ "$ARCH" == "x86_64" ] && [[ ${TARGET_VER%.*} -ge 16 ]] && ! check_x86_64_v2_support; then
                #echo "Unsupported CPU for openSUSE Leap $TARGET_VER"
                dialog --clear \
                    --title "System Migration - Unsupported architecture" \
	--msgbox "\n${MIGRATION_OPTIONS[$CHOICE]} does not support your CPU architecture. The minimum baseline is x86_64-v2.\n\nSee https://en.opensuse.org/openSUSE:X86-64-Architecture-Levels" \
    10 60
    reset; exit 1
            fi
                
            $DRYRUN zypper addrepo -f https://download.opensuse.org/distribution/leap/$TARGET_VER/repo/oss $TMP_REPO_NAME
            $DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME openSUSE-repos-Leap # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated

            $DRYRUN zypper --releasever $TARGET_VER dup -y --force-resolution --allow-vendor-change --download-in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper --releasever $TARGET_VER dup --force-resolution --allow-vendor-change --download-in-advance
            fi
            ;;
        *"MicroOS-Slowroll"*)
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # https://download.opensuse.org/ports/ # for other arches
            REPOURL="https://download.opensuse.org/slowroll/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                # Let's not messup any systems and make sure this is properly implemented first
                echo "Unsupported arch '$ARCH'."
                echo "Please open an issue at https://github.com/openSUSE/opensuse-migration-tool/issues"
                echo "Make sure to add output of 'uname -i' and content of your /etc/os-release into the ticket."
                exit 1
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
			$DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME --allow-downgrade openSUSE-repos-Slowroll # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated

            # --allow-downgrade is important in case that you choose MicroOS -> MicroOS-Slowroll migration
            $DRYRUN zypper dup -y --force-resolution --allow-downgrade --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-downgrade --allow-vendor-change --download in-advance
            fi
            ;;
        *"MicroOS"*)
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # https://download.opensuse.org/ports/ # for other arches
            REPOURL="https://download.opensuse.org/tumbleweed/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                REPOURL=https://download.opensuse.org/ports/$ARCH # XXX this will likely work only for aarch64
                if [ "$ARCH" != "aarch64" ]; then 
                    # Let's not messup any systems and make sure this is properly implemented first
                    echo "Unsupported arch '$ARCH'."
                    echo "Please open an issue at https://github.com/openSUSE/opensuse-migration-tool/issues"
                    echo "Make sure to add output of 'uname -i' and content of your /etc/os-release into the ticket."
                    exit 1
                fi
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
			$DRYRUN zypper install --repo $TMP_REPO_NAME -y --force-resolution --from $TMP_REPO_NAME openSUSE-repos-MicroOS # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refresh-services # !Important! make sure that all repo files under index service were regenerated
            
            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi
            ;;
    esac
else
    echo "No option selected. Exiting."
    exit 1
fi

# Migration scripts, keep the desc short

for script in "$POST_MIGRATION_DIR"/*.sh; do
    name=$(basename "$script" .sh)
    if "$script" --check; then
        case "$name" in
            "10_keepapparmor") desc="Keep AppArmor (SELinux is the new default)" ;;
            "10_keepselinux") desc="Switch to SELinux (new default)" ;;
            "20_pulse2pipewire") desc="Switch to PipeWire (new default)" ;;
            "20_ia32") desc="Allow 32bit binary execution (Steam)" ;;
            *)                   desc="Run $name" ;;
        esac
        AVAILABLE_TASKS["$name"]="$desc"
    fi
done

if [[ ${#AVAILABLE_TASKS[@]} -gt 0 ]]; then
    CHECKLIST_ITEMS=()
    for key in "${!AVAILABLE_TASKS[@]}"; do
        CHECKLIST_ITEMS+=("$key" "${AVAILABLE_TASKS[$key]}" "off")
    done
    SELECTED_TASKS=$(dialog --clear \
        --title "Post-Migration Optional Tasks" \
        --checklist "Select tasks to run after system upgrade:" \
        20 70 10 \
        "${CHECKLIST_ITEMS[@]}" \
        2>&1 >/dev/tty)
else
    echo "[INFO] No available post-migration tasks."
fi

# Basic ordering of execution
# We use prefixes and simple string comparison e.g. scripts/05_script.sh ...
sorted_selected_tasks=$(echo $SELECTED_TASKS | tr ' ' '\n' | sort)
for task in $sorted_selected_tasks; do
    SCRIPT="$POST_MIGRATION_DIR/$task.sh"
    echo "[INFO] Running post-migration task: $task"
    $DRYRUN $SCRIPT
done

if [[ -n "$DRYRUN" ]] ; then
	echo "Dry run completed, feel free to continue. "
else
#dialog --clear \
#    --backtitle "[EXPERIMENTAL] Migration tool" \
#    --title "Migration process completed" \
#    --msgbox "\nMigration process completed.\nA reboot is recommended." 10 40
#
	echo "Migration process completed. A reboot is recommended."
fi
