#!/bin/bash

# ==============================================================================
# DOS ARJ-Packer & Floppy-IMA Generator (über DOSBox & echte ARJ.EXE)
# ==============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_NAME=$(basename "$0")

if [ "$#" -lt 3 ]; then
    echo -e "\nNutzung: $SCRIPT_NAME <ARCHIVNAME_8> <QUELLORDNER> <DISKGROESSE> [PFAD_BEHALTEN 0|1]\n"
    echo "Parameter:"
    echo "  ARCHIVNAME_8  : Name ohne Endung (max. 8 Zeichen, z.B. PCKCOL)"
    echo "  QUELLORDNER   : Pfad zum Quellverzeichnis"
    echo "  DISKGROESSE   : Disketten-Größe: 1.44 (MB), 1.2 (MB), 720 (kB), 360 (kB)"
    echo "  PFAD_BEHALTEN : 0 = Nur Inhalt packen / Root ist Ordnerinhalt (Standard)"
    echo "                  1 = Quellordner als ARCHIVNAME_8 im Archiv mitpacken"
    echo ""
    echo "Beispiel:"
    echo "  $SCRIPT_NAME PCKCOL \"/home/user/PCKCOL\" 1.44 0"
    exit 1
fi

ARCHIVE_BASE="$1"
SRC_DIR="$2"
DISK_SIZE_INPUT="$3"
PRESERVE_PATH="${4:-0}"

# ------------------------------------------------------------------------------
# 1. Abhängigkeiten & ARJ.EXE prüfen
# ------------------------------------------------------------------------------
DOSBOX_BIN=""
if command -v dosbox-staging &> /dev/null; then
    DOSBOX_BIN="dosbox-staging"
elif command -v dosbox &> /dev/null; then
    DOSBOX_BIN="dosbox"
else
    echo -e "\nFehler: Weder 'dosbox-staging' noch 'dosbox' wurde gefunden. Bitte installieren."
    exit 1
fi

for cmd in dd mformat mcopy du; do
    if ! command -v $cmd &> /dev/null; then
        echo -e "\nFehler: Befehl '$cmd' wurde nicht gefunden. Bitte installieren."
        exit 1
    fi
done

ARJ_EXE=""
if [ -f "$SCRIPT_DIR/ARJ.EXE" ]; then
    ARJ_EXE="$SCRIPT_DIR/ARJ.EXE"
elif [ -f "./ARJ.EXE" ]; then
    ARJ_EXE="$(pwd)/ARJ.EXE"
fi

if [ -z "$ARJ_EXE" ]; then
    echo -e "\nFehler: 'ARJ.EXE' (16-Bit DOS Executable) wurde nicht gefunden!"
    echo "Bitte lege die DOS-Datei 'ARJ.EXE' in folgenden Ordner: $SCRIPT_DIR"
    exit 1
fi

# ------------------------------------------------------------------------------
# 2. DOS 8-Zeichen Name prüfen
# ------------------------------------------------------------------------------
if [[ ! "$ARCHIVE_BASE" =~ ^[a-zA-Z0-9_-]{1,8}$ ]]; then
    echo -e "\nFehler: Archivname '$ARCHIVE_BASE' entspricht nicht dem DOS-8-Format!"
    echo "Er darf maximal 8 Zeichen lang sein und keine Leer- oder Sonderzeichen enthalten."
    exit 1
fi

ARCHIVE_BASE="${ARCHIVE_BASE^^}"
ARCHIVE_NAME="${ARCHIVE_BASE}.ARJ"

# ------------------------------------------------------------------------------
# 3. Pfade auflösen
# ------------------------------------------------------------------------------
if [ ! -d "$SRC_DIR" ]; then
    echo -e "\nFehler: Quellverzeichnis '$SRC_DIR' wurde nicht gefunden!"
    exit 1
fi

ABS_SRC_DIR=$(cd "$SRC_DIR" && pwd)
PARENT_DIR=$(dirname "$ABS_SRC_DIR")
ORIGINAL_FOLDER_NAME=$(basename "$ABS_SRC_DIR")

# ------------------------------------------------------------------------------
# 4. Disketten-Spezifikationen festlegen
# ------------------------------------------------------------------------------
case "$DISK_SIZE_INPUT" in
    1.44|1440)
        ARJ_SPLIT="1440"
        DD_COUNT=1440
        MFORMAT_SIZE=1440
        MAX_DISK_BYTES=1457664
        ;;
    1.2|1200)
        ARJ_SPLIT="1200"
        DD_COUNT=1200
        MFORMAT_SIZE=1200
        MAX_DISK_BYTES=1213952
        ;;
    720)
        ARJ_SPLIT="720"
        DD_COUNT=720
        MFORMAT_SIZE=720
        MAX_DISK_BYTES=730112
        ;;
    360)
        ARJ_SPLIT="360"
        DD_COUNT=360
        MFORMAT_SIZE=360
        MAX_DISK_BYTES=362496
        ;;
    *)
        echo -e "\nFehler: Ungültige Diskettengröße '$DISK_SIZE_INPUT'!"
        echo "Erlaubte Werte: 1.44, 1.2, 720, 360"
        exit 1
        ;;
esac

# ------------------------------------------------------------------------------
# 5. Größenprüfung des Quellordners
# ------------------------------------------------------------------------------
FOLDER_BYTES=$(du -sb "$ABS_SRC_DIR" 2>/dev/null | awk '{print $1}')

if [ -n "$FOLDER_BYTES" ] && [ "$FOLDER_BYTES" -lt "$MAX_DISK_BYTES" ]; then
    WARN_PCT=$(( FOLDER_BYTES * 100 / MAX_DISK_BYTES ))
    echo "-------------------------------------------------------------------------------"
    echo "💡 HINWEIS: Der Quellordner belegt unkomprimiert nur ${WARN_PCT}% einer"
    echo "   Diskette ($FOLDER_BYTES von $MAX_DISK_BYTES Bytes)."
    echo "   Die Dateien würden direkt unkomprimiert auf eine Diskette passen."
    echo "-------------------------------------------------------------------------------"
fi

# ------------------------------------------------------------------------------
# 6. Trap für sicheres Aufräumen bei Abbruch
# ------------------------------------------------------------------------------
RENAMED=0
TMP_DOS_DIR=""
TMP_CONF=""

cleanup() {
    [ -n "$TMP_DOS_DIR" ] && [ -d "$TMP_DOS_DIR" ] && rm -rf "$TMP_DOS_DIR"
    [ -n "$TMP_CONF" ] && [ -f "$TMP_CONF" ] && rm -f "$TMP_CONF"
    if [ "$RENAMED" -eq 1 ] && [ -d "$PARENT_DIR/$ARCHIVE_BASE" ]; then
        echo -e "\nStelle ursprünglichen Ordnernamen wieder her..."
        mv "$PARENT_DIR/$ARCHIVE_BASE" "$ABS_SRC_DIR"
    fi
}
trap cleanup EXIT INT TERM

# ------------------------------------------------------------------------------
# 7. Isolierte Temp-Umgebung & leere DOSBox-Config anlegen
# ------------------------------------------------------------------------------
TMP_DOS_DIR=$(mktemp -d)
cp "$ARJ_EXE" "$TMP_DOS_DIR/ARJ.EXE"

TMP_CONF=$(mktemp --suffix=.conf)
cat << 'EOF' > "$TMP_CONF"
[sdl]
display = 0
[cpu]
core = dynamic
cputype = auto
cycles = max
[autoexec]
EOF

LOG_FILE="$TMP_DOS_DIR/dosbox.log"

echo "-------------------------------------------------------------------------------"
echo "1. Erstelle echtes DOS ARJ-Archiv in DOSBox ($DOSBOX_BIN): $ARCHIVE_NAME"
echo "   Split-Preset: -v$ARJ_SPLIT"
echo "-------------------------------------------------------------------------------"

if [ "$PRESERVE_PATH" -eq 1 ]; then
    if [ "$ORIGINAL_FOLDER_NAME" != "$ARCHIVE_BASE" ]; then
        if [ -e "$PARENT_DIR/$ARCHIVE_BASE" ]; then
            echo -e "\nFehler: Zielpfad '$PARENT_DIR/$ARCHIVE_BASE' existiert bereits!"
            exit 1
        fi
        mv "$ABS_SRC_DIR" "$PARENT_DIR/$ARCHIVE_BASE"
        RENAMED=1
    fi

    "$DOSBOX_BIN" -nogui -noconfig -conf "$TMP_CONF" \
        -c "MOUNT C \"$TMP_DOS_DIR\"" \
        -c "MOUNT D \"$PARENT_DIR\"" \
        -c "C:" \
        -c "D:" \
        -c "C:\ARJ.EXE a -r -y -m1 -v$ARJ_SPLIT C:\\$ARCHIVE_NAME $ARCHIVE_BASE\\*.*" \
        -c "EXIT" &> "$LOG_FILE"
else
    "$DOSBOX_BIN" -nogui -noconfig -conf "$TMP_CONF" \
        -c "MOUNT C \"$TMP_DOS_DIR\"" \
        -c "MOUNT D \"$ABS_SRC_DIR\"" \
        -c "C:" \
        -c "D:" \
        -c "C:\ARJ.EXE a -r -y -m1 -v$ARJ_SPLIT C:\\$ARCHIVE_NAME *.*" \
        -c "EXIT" &> "$LOG_FILE"
fi

# Erzeugte Archive aus dem Temp-Ordner ins aktuelle Verzeichnis holen
mv "$TMP_DOS_DIR"/${ARCHIVE_BASE}.* "$(pwd)/" 2>/dev/null

if [ ! -f "${ARCHIVE_BASE}.ARJ" ]; then
    echo -e "\nFehler beim Erstellen des ARJ-Archivs via DOSBox!"
    if [ -f "$LOG_FILE" ]; then
        echo "--- DOSBox Log ---"
        cat "$LOG_FILE"
        echo "------------------"
    fi
    exit 1
fi

# ------------------------------------------------------------------------------
# 8. Disketten-Images (.IMA) erzeugen, formatieren & befüllen
# ------------------------------------------------------------------------------
echo -e "\n-------------------------------------------------------------------------------"
echo "2. Erstelle .IMA Disketten-Image(s)"
echo "-------------------------------------------------------------------------------"

ARJ_FILES=()
[ -f "${ARCHIVE_BASE}.ARJ" ] && ARJ_FILES+=("${ARCHIVE_BASE}.ARJ")

while IFS= read -r file; do
    if [ -n "$file" ] && [ "$file" != "${ARCHIVE_BASE}.ARJ" ]; then
        ARJ_FILES+=("$file")
    fi
done < <(ls "${ARCHIVE_BASE}".A* 2>/dev/null | sort)

TOTAL_DISKS=${#ARJ_FILES[@]}
DISK_INDEX=1

for arj_part in "${ARJ_FILES[@]}"; do
    if [ "$TOTAL_DISKS" -eq 1 ]; then
        IMA_NAME="${ARCHIVE_BASE}.IMA"
        VOLUME_LABEL="${ARCHIVE_BASE:0:11}"
    else
        IDX_STR=$(printf "%02d" $DISK_INDEX)
        IMA_NAME="${ARCHIVE_BASE}_DISK${IDX_STR}.IMA"
        VOLUME_LABEL="${ARCHIVE_BASE:0:8}_${DISK_INDEX}"
    fi

    echo -n " -> Erstelle $IMA_NAME ($arj_part)... "

    dd if=/dev/zero of="$IMA_NAME" bs=1k count=$DD_COUNT status=none
    if [ $? -ne 0 ]; then echo "FEHLER (dd)"; exit 1; fi

    mformat -i "$IMA_NAME" -f $MFORMAT_SIZE -v "$VOLUME_LABEL" ::
    if [ $? -ne 0 ]; then echo "FEHLER (mformat)"; exit 1; fi

    mcopy -i "$IMA_NAME" "$arj_part" ::
    if [ $? -ne 0 ]; then echo "FEHLER (mcopy)"; exit 1; fi

    echo "OK! [Label: $VOLUME_LABEL]"
    ((DISK_INDEX++))
done

echo -e "\n-------------------------------------------------------------------------------"
echo "Fertig! Erstellte Disketten-Images:"
if [ "$TOTAL_DISKS" -eq 1 ]; then
    ls -lh "${ARCHIVE_BASE}.IMA"
else
    ls -lh ${ARCHIVE_BASE}_DISK*.IMA
fi
echo "-------------------------------------------------------------------------------"

exit 0
