#!/bin/bash
#
# update_ecmwf_webpage.sh
#
# Bash port of update_ecmwf_webpage.py. For every forecast base directory it
#   1) finds subdirectories named YYYYMMDDHHMM,
#   2) splits them into empty and filled ones,
#   3) writes a new settings.php ($init_times line) from a template,
#   4) deletes old empty subdirectories,
#   5) deletes old filled subdirectories (archiving disabled, as in the original),
#   6) creates subdirectories for future incoming forecasts.
#
# Requirements: bash >= 4 (mapfile, associative arrays), GNU date.

############################################################################
# SETTINGS
############################################################################

campaignName="dlr/ipa missionsupport classic webpage"

# "baseDir:settingsTemplate" pairs (replaces the python tuples; the original
# loop unpacked 3 values from 2-element tuples -- this is what was meant).
forecastBases=(
    "/var/www/html/forecasts:/var/www/html/scripts/settings_template_forecasts.php"
)

numberSelectableForecasts=6       # runs selectable in the drop-down box
createDirsNumberRunsInAdvance=10  # future dirs to pre-create (12h steps)
deleteEmptyDirsOlderThanDays=1

# Optional file renaming, as in the python version
renameFiles=false
declare -A filenameReplacementTable=(
    ["_52_"]="_200_"  ["_55_"]="_250_"  ["_60_"]="_300_"  ["_64_"]="_500_"
    ["_71_"]="_700_"  ["_77_"]="_850_"  ["_81_"]="_925_"  ["_88_"]="_1000_"
)

############################################################
# HELPERS
############################################################

# YYYYMMDDHHMM -> "YYYY-MM-DD HH:MM:SS"
ts2iso() {
    printf '%s-%s-%s %s:%s:00' \
        "$(printf '%s' "$1" | cut -c1-4)"  \
        "$(printf '%s' "$1" | cut -c5-6)"  \
        "$(printf '%s' "$1" | cut -c7-8)"  \
        "$(printf '%s' "$1" | cut -c9-10)" \
        "$(printf '%s' "$1" | cut -c11-12)"
}

# shift_ts TIMESTAMP SECONDS  ->  TIMESTAMP + SECONDS
shift_ts() {
    epoch=$(date -u -d "$(ts2iso "$1")" +%s)
    date -u -d "@$(( epoch + $2 ))" +%Y%m%d%H%M
}

# print a newline-separated list indented by two spaces
# (prints nothing if the list is empty)
print_list() {
    if [ -n "$1" ]; then
        printf '%s\n' "$1" | sed 's/^/  /'
    fi
}

############################################################################
# MAIN PROGRAM
############################################################################

echo "*****************************************************************"
echo "ecmwf forecasts web page processing for $campaignName"
echo "starting at $(date -u) on $(hostname)"
# Current time and last ECMWF init (last 00 or 12 UTC run)
now=$(date -u +%Y%m%d%H%M)
if [ "$(printf '%s' "$now" | cut -c9-10)" -lt 12 ]; then
    lastInitHour=00
else
    lastInitHour=12
fi
lastECMWFInit="$(printf '%s' "$now" | cut -c1-8)${lastInitHour}00"
# -> ends in 0000 or 1200, never 0100

cutoffNoFilled=$(shift_ts "$lastECMWFInit" $(( deleteEmptyDirsOlderThanDays * -86400 )))

# Base for the pre-created directories:
preCreateStart=$lastECMWFInit       # first created dir = 2026-11-13 00:00
# preCreateStart=$cutoffNoFilled   # original python behaviour: starts 1 day earlier

for entry in "${forecastBases[@]}"; do

    forecastBaseDir="${entry%%:*}"
    settingsTemplate="${entry##*:}"

    echo
    echo
    echo "processing base directory is $forecastBaseDir"

    # ---- 1) collect subdirectories named YYYYMMDDHHMM --------------------
    forecastDirs=()
    for path in "$forecastBaseDir"/*/; do
        [ -d "$path" ] || continue
        name=${path%/}; name=${name##*/}
        [[ $name =~ ^[0-9]{12}$ ]] && forecastDirs+=("$name")
    done

    # ---- 2) split into empty / filled -------------------------------------
    emptyForecastDirs=()
    filledForecastDirs=()
    for d in "${forecastDirs[@]}"; do
        if [ -z "$(ls -A "$forecastBaseDir/$d" 2>/dev/null)" ]; then
            emptyForecastDirs+=("$d")
        else
            filledForecastDirs+=("$d")
        fi
    done

    # fixed-width names: lexical sort == chronological sort
    if ((${#emptyForecastDirs[@]})); then
        mapfile -t emptyForecastDirs < <(printf '%s\n' "${emptyForecastDirs[@]}" | sort)
    fi
    if ((${#filledForecastDirs[@]})); then
        mapfile -t filledForecastDirs < <(printf '%s\n' "${filledForecastDirs[@]}" | sort -r)
    fi

    echo
    echo "base directory contains as empty subdirectories:"
    print_list "${emptyForecastDirs[@]}"

    echo
    echo "base directory contains as filled subdirectories:"
    print_list "${filledForecastDirs[@]}"

    # ---- 3) write settings.php --------------------------------------------
    selectableForecastDirs=()
    if ((${#filledForecastDirs[@]} > 0)); then
        n=$numberSelectableForecasts
        ((${#filledForecastDirs[@]} < n)) && n=${#filledForecastDirs[@]}
        selectableForecastDirs=("${filledForecastDirs[@]:0:n}")
    fi

    echo
    echo "forecast runs that will be selectable on the webpage (written to settings.php):"
    print_list "${selectableForecastDirs[@]}"

    initTimesLine='  $init_times = array('
    sep=''
    for d in "${selectableForecastDirs[@]}"; do
        initTimesLine+="${sep}\"${d}\""
        sep=', '
    done
    initTimesLine+=');'

    settingsFileName="$forecastBaseDir/settings.php"
    echo "  Writing $settingsFileName"
    awk -v newline="$initTimesLine" \
        'index($0, "$init_times") > 0 { print newline; next } { print }' \
        "$settingsTemplate" > "$settingsFileName.tmp" \
        && mv "$settingsFileName.tmp" "$settingsFileName"
    chmod 664 "$settingsFileName"          # rw-rw-r--, as in the python version

    # ---- 4) delete old empty subdirectories -------------------------------
    emptyDirsToDelete=()
    if ((${#filledForecastDirs[@]} > 0)); then
        for d in "${emptyForecastDirs[@]}"; do
            [[ $d < "${filledForecastDirs[0]}" ]] && emptyDirsToDelete+=("$d")
        done
    else
        # no filled dirs: delete empty dirs older than lastInit - N days
        for d in "${emptyForecastDirs[@]}"; do
            [[ $d < "$cutoffNoFilled" ]] && emptyDirsToDelete+=("$d")
        done
    fi

    echo
    echo "empty subdirectories to be deleted:"
    print_list "${emptyDirsToDelete[@]}"

    for d in "${emptyDirsToDelete[@]}"; do
        echo "  removing $d"
        rmdir "$forecastBaseDir/$d" 2>/dev/null || echo "	an error occurred, skipping."
    done

    # ---- optional: rename files --------------------------------------------
    if [ "$renameFiles" = true ]; then
        echo
        echo "renaming files."
        for d in "${filledForecastDirs[@]}"; do
            for f in "$forecastBaseDir/$d"/*; do
                [ -e "$f" ] || continue
                name=${f##*/}; newname=$name
                for key in "${!filenameReplacementTable[@]}"; do
                    [[ $newname == *"$key"* ]] \
                        && newname=${newname//"$key"/${filenameReplacementTable[$key]}}
                done
                [[ $newname != "$name" ]] && mv -f "$f" "$forecastBaseDir/$d/$newname"
            done
        done
    fi

    # ---- 5) delete old filled subdirectories (archiving disabled, as original)
    filledDirsToArchive=()
    if ((${#filledForecastDirs[@]} > numberSelectableForecasts)); then
        filledDirsToArchive=("${filledForecastDirs[@]:numberSelectableForecasts}")
    fi

    echo
    echo "old filled forecast subdirectories to be archived:"
    print_list "${filledDirsToArchive[@]}"

    # To re-enable tar.gz archiving, uncomment:
    # for d in "${filledDirsToArchive[@]}"; do
    #     tar czf "/home/archives/${d}.tar.gz" -C "$forecastBaseDir" "$d"
    # done
    for d in "${filledDirsToArchive[@]}"; do
        echo "  Deleting $d"
        rm -rf "$forecastBaseDir/$d" || echo "	an error occurred, skipping."
    done

    # ---- 6) create subdirectories for future forecasts ---------------------
    echo
    echo "new subdirectories for incoming forecasts to be created:"
    
    run=0
    while [ "$run" -le "$createDirsNumberRunsInAdvance" ]; do
        d=$(shift_ts "$preCreateStart" $(( run * 43200 )))
        echo "  Creating directory $d"
        if mkdir "$forecastBaseDir/$d" 2>/dev/null; then
            chmod 775 "$forecastBaseDir/$d"
        else
            printf '\texists, skipping.\n'
        fi
        run=$((run + 1))
    done 
    
done

echo
echo
echo "processing finished at $(date)"
echo "*****************************************************************"
