#!/bin/bash
# =============================================================================
# wiris-dtb-config: Nástroj pro správu a přepínání Device Tree na SP7021 Wiris
# =============================================================================

set -e

DTB_CONFIGS_DIR="/boot/dtb-configs"
ACTIVE_DTB_FILE="/boot/dtb"
CONF_FILE="/etc/wiris/board.conf"
CONF_DIR="/etc/wiris"

# Kontrola root oprávnění pro modifikační operace
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "CHYBA: Tato operace vyžaduje administrátorská práva (spusťte se sudo)." >&2
        exit 1
    fi
}

# Kontrola, zda je /boot připojen
check_boot_mount() {
    if ! mountpoint -q /boot; then
        echo "CHYBA: /boot není připojen jako samostatný oddíl (boot partition)!" >&2
        exit 1
    fi
}

# Zjištění běžícího modelu z Device Tree
get_running_model() {
    if [ -f /sys/firmware/devicetree/base/model ]; then
        tr -d '\0' < /sys/firmware/devicetree/base/model
    else
        echo "Neznámý (Device Tree /sys není dostupné)"
    fi
}

# Zjištění, který DTB z /boot/dtb-configs je aktuálně aktivní v /boot/dtb
get_active_dtb() {
    if [ ! -f "$ACTIVE_DTB_FILE" ]; then
        echo "žádný (soubor $ACTIVE_DTB_FILE neexistuje)"
        return
    fi

    local active_hash
    active_hash=$(sha256sum "$ACTIVE_DTB_FILE" 2>/dev/null | awk '{print $1}')

    for dtb in "$DTB_CONFIGS_DIR"/*.dtb; do
        [ -f "$dtb" ] || continue
        local cur_hash
        cur_hash=$(sha256sum "$dtb" 2>/dev/null | awk '{print $1}')
        if [ "$active_hash" = "$cur_hash" ]; then
            basename "$dtb"
            return
        fi
    done

    # Fallback na konfiguraci, pokud se hashe neshodují
    if [ -f "$CONF_FILE" ]; then
        # shellcheck source=/dev/null
        . "$CONF_FILE"
        if [ -n "$ACTIVE_DTB" ]; then
            echo "$ACTIVE_DTB (podle konfigurace, obsah se může lišit)"
            return
        fi
    fi

    echo "vlastní / neznámý"
}

# Výpis dostupných profilů
cmd_list() {
    echo "============================================================"
    echo "  SP7021 Wiris - Device Tree konfigurace"
    echo "============================================================"
    echo "Běžící model v RAM:   $(get_running_model)"
    echo "Aktivní na bootu:     $(get_active_dtb)"
    echo ""
    echo "Dostupné DTB profily v $DTB_CONFIGS_DIR:"

    local active_name
    active_name=$(get_active_dtb)
    local i=1

    if [ ! -d "$DTB_CONFIGS_DIR" ] || [ -z "$(ls -A "$DTB_CONFIGS_DIR"/*.dtb 2>/dev/null)" ]; then
        echo "  (žádné DTB profily nenalezeny v $DTB_CONFIGS_DIR)"
        return
    fi

    for dtb in "$DTB_CONFIGS_DIR"/*.dtb; do
        [ -f "$dtb" ] || continue
        local name
        name=$(basename "$dtb")
        if [ "$name" = "$active_name" ]; then
            printf "  * %2d) %-40s [AKTIVNÍ]\n" "$i" "$name"
        else
            printf "    %2d) %-40s\n" "$i" "$name"
        fi
        i=$((i + 1))
    done
    echo "============================================================"
}

# Nastavení a aktivace konkrétního DTB
cmd_set() {
    local target="$1"
    check_root
    check_boot_mount

    if [ -z "$target" ]; then
        echo "CHYBA: Nebyl zadán název DTB profilu." >&2
        echo "Použití: wiris-dtb set <nazev_profilu.dtb>" >&2
        exit 1
    fi

    local target_file=""

    # 1. Hledání přesného souboru
    if [ -f "$DTB_CONFIGS_DIR/$target" ]; then
        target_file="$DTB_CONFIGS_DIR/$target"
    elif [ -f "$DTB_CONFIGS_DIR/$target.dtb" ]; then
        target_file="$DTB_CONFIGS_DIR/$target.dtb"
    else
        # 2. Hledání podle části názvu
        local matches=()
        for f in "$DTB_CONFIGS_DIR"/*"$target"*.dtb; do
            [ -f "$f" ] && matches+=("$f")
        done
        if [ ${#matches[@]} -eq 1 ]; then
            target_file="${matches[0]}"
        elif [ ${#matches[@]} -gt 1 ]; then
            echo "CHYBA: Nalezeno více profilů odpovídajících '$target':" >&2
            for m in "${matches[@]}"; do
                echo "  - $(basename "$m")" >&2
            done
            exit 1
        else
            echo "CHYBA: DTB profil '$target' nebyl v $DTB_CONFIGS_DIR nalezen." >&2
            echo "Dostupné profily zobrazíte příkazem: wiris-dtb list" >&2
            exit 1
        fi
    fi

    local dtb_filename
    dtb_filename=$(basename "$target_file")

    echo "Aktivuji Device Tree profil: $dtb_filename"
    cp -f "$target_file" "$ACTIVE_DTB_FILE"
    sync

    # Uložení do konfigurace
    mkdir -p "$CONF_DIR"
    echo "# SP7021 Wiris Board Configuration" > "$CONF_FILE"
    echo "ACTIVE_DTB=\"$dtb_filename\"" >> "$CONF_FILE"

    echo "[OK] Profil '$dtb_filename' byl úspěšně zapsán do $ACTIVE_DTB_FILE"
    echo "[INFO] Změna se projeví po restartu zařízení (spusťte 'sudo reboot')."
}

# Aplikace konfigurace (používáno interně v postinst)
cmd_apply() {
    check_root
    check_boot_mount

    local dtb_to_apply=""

    if [ -f "$CONF_FILE" ]; then
        # shellcheck source=/dev/null
        . "$CONF_FILE"
        dtb_to_apply="$ACTIVE_DTB"
    fi

    if [ -z "$dtb_to_apply" ] || [ ! -f "$DTB_CONFIGS_DIR/$dtb_to_apply" ]; then
        # Fallback na první nalezený DTB soubor
        local first_dtb
        first_dtb=$(ls -1 "$DTB_CONFIGS_DIR"/*.dtb 2>/dev/null | head -n 1)
        if [ -n "$first_dtb" ]; then
            dtb_to_apply=$(basename "$first_dtb")
        fi
    fi

    if [ -n "$dtb_to_apply" ] && [ -f "$DTB_CONFIGS_DIR/$dtb_to_apply" ]; then
        cp -f "$DTB_CONFIGS_DIR/$dtb_to_apply" "$ACTIVE_DTB_FILE"
        sync
        mkdir -p "$CONF_DIR"
        echo "# SP7021 Wiris Board Configuration" > "$CONF_FILE"
        echo "ACTIVE_DTB=\"$dtb_to_apply\"" >> "$CONF_FILE"
        echo "DTB profil '$dtb_to_apply' aplikován na $ACTIVE_DTB_FILE."
    else
        echo "VAROVÁNÍ: Žádný platný DTB profil k aplikaci nebyl nalezen v $DTB_CONFIGS_DIR." >&2
    fi
}

# Interaktivní menu
cmd_interactive() {
    cmd_list
    echo ""

    local dtbs=()
    for dtb in "$DTB_CONFIGS_DIR"/*.dtb; do
        [ -f "$dtb" ] && dtbs+=("$dtb")
    done

    if [ ${#dtbs[@]} -eq 0 ]; then
        exit 0
    fi

    read -r -p "Zadejte číslo profilu pro aktivaci (nebo Enter/q pro konec): " choice
    if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#dtbs[@]}" ]; then
        local selected_dtb="${dtbs[$((choice - 1))]}"
        cmd_set "$(basename "$selected_dtb")"
    else
        echo "Konec bez provedení změn."
    fi
}

# Nápověda
cmd_help() {
    echo "Použití: wiris-dtb <příkaz> [argumenty]"
    echo ""
    echo "Příkazy:"
    echo "  list, status        Zobrazí dostupné profily a aktuálně aktivní DTB"
    echo "  set <profil>        Přepne a aktivuje vybraný DTB profil na /boot/dtb"
    echo "  apply               Znovu aplikuje aktivní profil z /etc/wiris/board.conf"
    echo "  help, -h, --help    Zobrazí tuto nápovědu"
    echo ""
    echo "Při spuštění bez parametrů v terminálu se otevře interaktivní menu."
}

# Hlavní router
case "${1:-}" in
    list|status)
        cmd_list
        ;;
    set|select)
        shift
        cmd_set "${1:-}"
        ;;
    apply)
        cmd_apply
        ;;
    help|-h|--help)
        cmd_help
        ;;
    "")
        if [ -t 0 ]; then
            cmd_interactive
        else
            cmd_list
        fi
        ;;
    *)
        # Pokud je první parametr název souboru/profilu, zkusíme rovnou set
        if [ -f "$DTB_CONFIGS_DIR/$1" ] || [ -f "$DTB_CONFIGS_DIR/$1.dtb" ]; then
            cmd_set "$1"
        else
            echo "Neznámý příkaz: $1" >&2
            cmd_help >&2
            exit 1
        fi
        ;;
esac
