#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
# Provision firmware locally; never upload the result to COPR.
set -euo pipefail
usage() {
    printf '%s\n' \
        'Usage: azurefin-extract-firmware SurfaceLaptop7.msi DESTDIR' \
        '       azurefin-extract-firmware --download DESTDIR' \
        '       azurefin-extract-firmware --bluetooth-address MAC [--root ROOT]' \
        'DESTDIR must be a writable image tree with Fedora WCN7850 firmware.' \
        'Downloads use a pinned Microsoft MSI and verify SHA-512 before extraction.' \
        'Bluetooth configuration is saved for the next boot; no service is restarted.' \
        'Do not redistribute the resulting firmware-inclusive image.'
}
if [[ ${1:-} == --help || ${1:-} == -h ]]; then
    usage
    exit 0
fi
if [[ ${1:-} == --bluetooth-address ]]; then
    [[ $# == 2 || ( $# == 4 && $3 == --root ) ]] || { usage >&2; exit 2; }
    address=${2^^}
    [[ $address =~ ^([0-9A-F]{2}:){5}[0-9A-F]{2}$ &&
       $address != 00:00:00:00:00:00 && $address != FF:FF:FF:FF:FF:FF ]] || {
        echo 'Use the factory Bluetooth public address reported by Windows.' >&2
        exit 2
    }
    root=$(realpath -e -- "${4:-/}")
    [[ -d $root/etc && ! -L $root/etc && ! -L $root/etc/romulus-bluetooth-address ]] || {
        echo 'Expected a real etc directory and a non-symlink address file.' >&2
        exit 1
    }
    config="$root/etc/romulus-bluetooth-address"
    if [[ -e $config ]]; then
        cp --backup=numbered -- "$config" "$config.backup"
    fi
    pending=$(mktemp "$root/etc/.romulus-bluetooth-address.XXXXXXXX")
    printf '%s\n' "$address" > "$pending"
    chmod 0644 "$pending"
    mv -fT -- "$pending" "$config"
    echo "Saved Bluetooth address to $config; it will be applied at next boot."
    exit 0
fi
if [[ $# -ne 2 || ( $1 == --* && $1 != --download ) ]]; then
    usage >&2
    exit 2
fi
destination=$(realpath -e -- "$2")
[[ -d $destination/usr/lib/firmware && -w $destination/usr/lib/firmware ]] || {
    echo 'DESTDIR needs writable usr/lib/firmware. Do not modify immutable /usr; provision a local image build instead.' >&2
    exit 1
}
if [[ $(stat -f -c %T "$destination/usr") == erofs ]]; then
    echo 'Cannot provision a running composefs/EROFS deployment; use a writable image build.' >&2
    exit 1
fi
if [[ $1 == --download ]]; then
    download=$(mktemp -d -t azurefin-download.XXXXXXXX)
    msi="$download/SurfaceLaptop7_ARM_Win11_26100_26.053.36539.0.msi"
    echo "Downloading pinned Microsoft firmware installer to $msi"
    curl --fail --location --proto '=https' --proto-redir '=https' --retry 3 \
        --connect-timeout 30 --output "$msi" \
        'https://download.microsoft.com/download/b7ca2c3f-d320-4795-be0f-529a0117abb4/SurfaceLaptop7_ARM_Win11_26100_26.053.36539.0.msi'
else
    msi=$(realpath -e -- "$1")
fi
printf '%s  %s\n' \
    a837256c64446fb44ee452eae269b9d3f8f0a374a39691559128189fd23d3cef38f84be3733a51b7d3103f57bdd6f79c64369ca4d3a7bedfa35298ead9f92c0e \
    "$msi" | sha512sum --check
work=$(mktemp -d -t azurefin-firmware.XXXXXXXX)
# Keep extraction output on failure for diagnosis; no recursive cleanup trap.
msiextract -C "$work" "$msi"
fw="$destination/usr/lib/firmware"
for name in adsp_dtbs.elf adspr.jsn adsps.jsn adspua.jsn battmgr.jsn \
    cdsp_dtbs.elf cdspr.jsn qcadsp8380.mbn qccdsp8380.mbn qcvss8380.mbn \
    qcdxkmsuc8380.mbn; do
    mapfile -d '' matches < <(find "$work" -type f -iname "$name" -print0)
    [[ ${#matches[@]} -gt 0 ]] || { echo "Missing firmware: $name" >&2; exit 1; }
    # Duplicate copies are acceptable only if byte-identical.
    for candidate in "${matches[@]}"; do
        cmp -- "${matches[0]}" "$candidate"
    done
    target="$fw/qcom/x1e80100/microsoft/Romulus/$name"
    if [[ $name == qcdxkmsuc8380.mbn ]]; then
        target="$fw/qcom/x1e80100/microsoft/$name"
    fi
    install -Dm644 "${matches[0]}" "$target"
done
# Patch the distribution's board data locally, never put firmware in this RPM.
board="$fw/ath12k/WCN7850/hw2.0/board-2.bin"
if [[ -f "$board" ]]; then
    cp -- "$board" "$work/board-2.bin"
elif [[ -f "$board.zst" ]]; then
    zstd -dc -- "$board.zst" > "$work/board-2.bin"
elif [[ -f "$board.xz" ]]; then
    xz -dc -- "$board.xz" > "$work/board-2.bin"
else
    echo "Install Fedora's WCN7850 firmware before extracting." >&2
    exit 1
fi
(
    cd "$work"
    /usr/libexec/azurefin/ath12k-bdencoder -e board-2.bin
    /usr/libexec/azurefin/azurefin-board-alias board-2.json
    /usr/libexec/azurefin/ath12k-bdencoder -c board-2.json
)
install -Dm644 "$work/board-2.bin" "$board"
echo "Installed verified firmware. Extraction retained at $work"
