#!/usr/bin/env bash
#
# ansi-to-png-converter-bash.sh
#
# Updated to sanitise the file name:
#   – Keeps only characters with ASCII codes 33‑126 (printable characters, no spaces)
#   – Removes any other characters (control codes, Unicode, spaces, etc.)
#
# Behaviour otherwise unchanged:
#   • Shows pixel‑width reference table
#   • Prompts for scaling factor (2‑8, default 3)
#   • Prompts for optional “ice‑colors” flag
#   • Finds the newest file, sanitises its name, deletes everything else
#   • Calls ansilove with the chosen flags
#   • Zips the resulting PNG into ansiupconverted.zip
#
# All user‑visible output is forced to pure ASCII.
#

# ----------------------------------------------------------------------
# Helper: print only ASCII characters (drops anything outside 0‑127)
ascii_echo() {
    printf "%s\n" "$*" | tr -cd '\11\12\15\40-\176'
}

# ----------------------------------------------------------------------
# Helper: sanitise a filename – keep only characters with ASCII codes 33‑126
sanitize_name() {
    local raw="$1"
    # Translate each character: keep if ord between 33 and 126, otherwise delete
    echo "$raw" | perl -pe 's/([^\x21-\x7e])//g'
}

# ----------------------------------------------------------------------
# Configuration
ALLOWED_SCALES=(2 3 4 5 6 7 8)      # 1× removed – ansilove cannot handle it
DEFAULT_SCALE=3
declare -A PIXEL_MAP=(
    [2]=1280
    [3]=1920
    [4]=2560
    [5]=3200
    [6]=3840
    [7]=4480
    [8]=5120
)

# ----------------------------------------------------------------------
# 1️⃣ Show pixel‑width reference table (ASCII only)
ascii_echo ""
ascii_echo "--- Render-prompt pixel reference ---"
ascii_echo "| Scale | Pixel width |"
ascii_echo "|-------|-------------|"
for s in "${!PIXEL_MAP[@]}"; do
    ascii_echo "| ${s}x    | ${PIXEL_MAP[$s]} px |"
done
ascii_echo "------------------------------------"
ascii_echo ""

# ----------------------------------------------------------------------
# 2️⃣ Prompt for scaling factor (2‑8)
ascii_echo "=== ansilove up-scaling selection ==="
ascii_echo "Available scale factors (default = ${DEFAULT_SCALE}):"
for s in "${ALLOWED_SCALES[@]}"; do
    if [[ $s -eq $DEFAULT_SCALE ]]; then
        ascii_echo "  ${s} (default)"
    else
        ascii_echo "  ${s}"
    fi
done

while true; do
    ascii_echo -n $'\n'"Enter desired scale [${DEFAULT_SCALE}]: "
    read -r scale_input
    if [[ -z $scale_input ]]; then
        SCALE=$DEFAULT_SCALE
        break
    fi
    if [[ $scale_input =~ ^[0-9]+$ ]] && [[ " ${ALLOWED_SCALES[*]} " == *" $scale_input "* ]]; then
        SCALE=$scale_input
        break
    fi
    ascii_echo "Please type a number from the list above (or press Enter for the default)."
done

# ----------------------------------------------------------------------
# 3️⃣ Prompt for ice‑colors flag
ascii_echo ""
ascii_echo "=== Ice-colors option ==="
ascii_echo "Ansilove can render the image using the special \"ice-colors\" palette."
ascii_echo "Controlled by the short flag -i."
while true; do
    ascii_echo -n "Enable ice-colors? (y/N): "
    read -r ice_input
    case "${ice_input,,}" in
        y|yes) ICE_FLAG="-i"; ICE_TEXT="enabled"; break ;;
        n|no|"") ICE_FLAG=""; ICE_TEXT="disabled"; break ;;
        *) ascii_echo "Please answer with 'y' (yes) or 'n' (no)." ;;
    esac
done
ascii_echo ""
ascii_echo "✅ Ice-colors ${ICE_TEXT}."

# ----------------------------------------------------------------------
# 4️⃣ Get target directory from command line
if [[ $# -ne 1 ]]; then
    ascii_echo "Usage: $0 <directory-containing-ans-files>"
    exit 1
fi
TARGET_DIR="$(realpath "$1")"

if [[ ! -d "$TARGET_DIR" ]]; then
    ascii_echo "[ERROR] Not a directory: $TARGET_DIR"
    exit 1
fi

# ----------------------------------------------------------------------
# 5️⃣ Find the newest regular file (any extension) in the directory
NEWEST_FILE=$(find "$TARGET_DIR" -maxdepth 1 -type f -printf '%T@ %p\n' \
              | sort -k1,1nr | head -n1 | cut -d' ' -f2-)

if [[ -z $NEWEST_FILE ]]; then
    ascii_echo "[ERROR] No regular files found in $TARGET_DIR"
    exit 1
fi

# ----------------------------------------------------------------------
# 6️⃣ Sanitise the file name (keep only ASCII 33‑126)
RAW_BASENAME="$(basename "$NEWEST_FILE")"
SAFE_BASENAME="$(sanitize_name "$RAW_BASENAME")"

# If sanitisation changed the name, rename the file
if [[ "$RAW_BASENAME" != "$SAFE_BASENAME" ]]; then
    SAFE_PATH="${TARGET_DIR}/${SAFE_BASENAME}"
    # Ensure we don't overwrite an existing file unintentionally
    if [[ -e "$SAFE_PATH" ]]; then
        ascii_echo "[ERROR] Sanitised filename already exists: $SAFE_BASENAME"
        exit 1
    fi
    mv "$NEWEST_FILE" "$SAFE_PATH"
    NEWEST_FILE="$SAFE_PATH"
    ascii_echo "[INFO] Renamed file to safe name: $SAFE_BASENAME"
fi

MOD_TIME=$(date -d @"$(stat -c %Y "$NEWEST_FILE")" '+%Y-%m-%d %H:%M:%S')
ascii_echo "[INFO] Newest file: $(basename "$NEWEST_FILE") (modified $MOD_TIME)"

# ----------------------------------------------------------------------
# 7️⃣ Delete everything else in the directory
shopt -s nullglob
for f in "$TARGET_DIR"/*; do
    [[ "$f" == "$NEWEST_FILE" ]] && continue
    rm -rf "$f"
done
shopt -u nullglob
ascii_echo "[INFO] Deleted all other files."

# ----------------------------------------------------------------------
# 8️⃣ Run ansilove
PNG_OUT="${TARGET_DIR}/$(basename "${NEWEST_FILE%.*}").png"
ANSILOVE_CMD=(ansilove -R "$SCALE")
[[ -n $ICE_FLAG ]] && ANSILOVE_CMD+=("$ICE_FLAG")
ANSILOVE_CMD+=(-o "$PNG_OUT" "$NEWEST_FILE")

ascii_echo "[INFO] Running ansilove..."
if ! "${ANSILOVE_CMD[@]}" > /dev/null 2>&1; then
    ascii_echo "[ERROR] ansilove failed. Check that ansilove is installed and the input file is valid."
    exit 1
fi
ascii_echo "[INFO] ansilove rendered PNG at ${SCALE}x scaling ${ICE_TEXT:+($ICE_TEXT)}: $(basename "$PNG_OUT")"

# ----------------------------------------------------------------------
# 9️⃣ Zip the PNG
ZIP_OUT="${TARGET_DIR}/ansiupconverted.zip"
if zip -j -q "$ZIP_OUT" "$PNG_OUT" > /dev/null; then
    ascii_echo "[INFO] Created zip archive: $(basename "$ZIP_OUT")"
else
    ascii_echo "[ERROR] Failed to create zip archive."
    exit 1
fi

# (Optional) Remove the intermediate PNG if you only need the zip:
# rm -f "$PNG_OUT"
# ascii_echo "[INFO] Removed intermediate PNG file."

ascii_echo ""
ascii_echo "🎉 SUCCESS – all steps completed."
exit 0
