#!/bin/sh
# Generate firmware-NNNN/versions.txt mapping the firmware version
# (date from pieeprom-YYYY-MM-DD.bin) to:
#   - the BUILD_TIMESTAMP embedded in the binary
#   - the source git hash embedded in the binary as "VERSION:<hash>"
#   - the release (default / latest / old) the file lives in.
# When a binary appears under more than one release the highest-
# precedence one wins: default > latest > old.
# Output is sorted newest-first and is whitespace-columnar so that
# awk can extract fields directly (header lines start with '#').

set -eu

SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
REPO_ROOT=$(CDPATH= cd -- "${SCRIPT_DIR}/.." && pwd)

command -v strings >/dev/null 2>&1 || {
    echo "strings not found. Install binutils." >&2
    exit 1
}

extract_field() {
    # extract_field <bin> <sed-expression>
    strings "$1" | sed -n "$2" | head -n 1
}

release_for_path() {
    rel="$1"
    case "${rel}" in
        default/*) echo "default" ;;
        latest/*)  echo "latest" ;;
        *)         echo "old" ;;
    esac
}

release_priority() {
    case "$1" in
        default) echo 1 ;;
        latest)  echo 2 ;;
        old)     echo 3 ;;
        *)       echo 9 ;;
    esac
}

write_versions_md() {
    family_dir="$1"
    out="${family_dir}/versions.txt"
    family=$(basename "${family_dir}")
    raw=$(mktemp)
    rows=$(mktemp)

    find "${family_dir}" -type f -name 'pieeprom-*.bin' | while read -r bin; do
        name=$(basename "${bin}" .bin)
        version=${name#pieeprom-}
        case "${version}" in
            [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;;
            *) continue ;;
        esac
        rel=${bin#"${family_dir}/"}
        release=$(release_for_path "${rel}")
        priority=$(release_priority "${release}")
        hash=$(extract_field "${bin}" 's/^VERSION://p')
        [ -n "${hash}" ] || hash="(unknown)"
        ts=$(extract_field "${bin}" 's/^BUILD_TIMESTAMP=//p')
        [ -n "${ts}" ] || ts=0
        printf '%s\t%s\t%s\t%s\t%s\n' \
            "${version}" "${ts}" "${hash}" "${priority}" "${release}"
    done > "${raw}"

    # Pick the highest-precedence release per (version, hash), then
    # sort newest-first by version (lexicographic on YYYY-MM-DD).
    sort -t '	' -k1,1 -k3,3 -k4,4n "${raw}" | awk -F '\t' '
        { key = $1 "\t" $3 }
        !(key in seen) { seen[key] = 1; print }
    ' | sort -t '	' -k1,1r > "${rows}"

    {
        printf '# %s firmware versions\n' "${family}"
        printf '#\n'
        printf '# Maps each pieeprom-YYYY-MM-DD.bin to the BUILD_TIMESTAMP\n'
        printf '# and source git hash embedded in the binary, plus the\n'
        printf '# release (default / latest / old) the file lives in. When\n'
        printf '# a binary appears in more than one release the highest-\n'
        printf '# precedence one wins:\n'
        printf '#     default > latest > old   (old = archived)\n'
        printf '#\n'
        printf '# Generated by tools/%s. Sorted newest-first.\n' "$(basename "$0")"
        printf '#\n'
        printf '# %-10s  %-10s  %-10s  %s\n' \
            "version" "build_epoch" "fw_git_hash" "release"
        while IFS='	' read -r version ts hash priority release; do
            [ "${ts}" -gt 0 ] 2>/dev/null || ts="-"
            printf '%-10s  %-10s  %-10s  %s\n' \
                "${version}" "${ts}" "${hash}" "${release}"
        done < "${rows}"
    } > "${out}"

    rm -f "${raw}" "${rows}"
    echo "Wrote ${out}"
}

for family in firmware-2711 firmware-2712; do
    dir="${REPO_ROOT}/${family}"
    [ -d "${dir}" ] || continue
    write_versions_md "${dir}"
done
