#!/usr/bin/env bash
set -euo pipefail

project_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
linux_root="$project_root/Linux"
version="$(sed -n 's/^maptoolsVersion=//p' "$project_root/application/gradle.properties" | head -n 1)"
if [[ -z "$version" ]]; then
    echo "maptoolsVersion fehlt in application/gradle.properties." >&2
    exit 1
fi
release_directory="$project_root/release/$version"
linux_release_directory="$release_directory/linux"
source_release_directory="$release_directory/source"
security_release_directory="$release_directory/security"
security_report_directory="$project_root/security/reports/$version"
jdk_home="$(bash "$project_root/scripts/bootstrap-linux-jdk.sh" | tail -n 1)"
bash "$project_root/scripts/bootstrap-dependencies.sh"
source "$project_root/scripts/drvfs-gradle-compat.sh"
configure_drvfs_gradle_compatibility "$linux_root" "$project_root"

# Keep Linux build state portable and inspectable beside the repository. Gradle must stay in the
# current client process because its daemon registry tries to apply unsupported POSIX modes on
# Windows DrvFS mounts. Matching the client and requested build JVM options prevents Gradle from
# starting even a single-use daemon.
available_kib="$(df -Pk "$linux_root" | awk 'NR == 2 { print $4 }')"
required_kib=$((8 * 1024 * 1024))
if (( available_kib < required_kib )); then
    echo "Linux-Build blockiert: Auf dem aktuellen Speicher sind nur $((available_kib / 1024)) MiB frei; benötigt werden mindestens 8192 MiB." >&2
    exit 1
fi
build_directory="$linux_root/build"
resolved_linux_root="$(realpath -m -- "$linux_root")"
resolved_build_directory="$(realpath -m -- "$build_directory")"
if [[ "$resolved_build_directory" != "$resolved_linux_root/build" ]]; then
    echo "Linux-Build blockiert: Unerwartetes Buildverzeichnis '$resolved_build_directory'." >&2
    exit 1
fi
# A release build must not reuse Kotlin output produced by Windows or another WSL identity. DrvFS
# can otherwise reject an atomic replacement even though the parent directory itself is writable.
rm -rf -- "$resolved_build_directory"

export JAVA_HOME="$jdk_home"
export PATH="$JAVA_HOME/bin:$PATH"
export GRADLE_USER_HOME="$linux_root/.gradle-user"
export GRADLE_OPTS="-Xmx3g -Xms64m -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant"
mkdir -p "$linux_root/.kotlin/sessions"

bash "$project_root/application/gradlew" \
    -p "$project_root/application" \
    --no-daemon \
    --no-configuration-cache \
    --max-workers=8 \
    -Dorg.gradle.internal.instrumentation.agent=false \
    "-Dorg.gradle.jvmargs=-Xmx3g -Xms64m -Dfile.encoding=UTF-8" \
    --project-cache-dir "$linux_root/.gradle-project-cache" \
    "-Pmaptools.buildRoot=$build_directory" \
    "-Pmaptools.releaseRoot=$build_directory/source" \
    "-Pkotlin.project.persistent.dir=$linux_root/.kotlin" \
    :core:desktopTest test :desktopApp:prepareWorkerLauncher cyclonedxBom sourceArchive

mkdir -p "$linux_release_directory" "$source_release_directory" "$security_release_directory" "$security_report_directory"
generated_source_archive="$build_directory/source/ArxSilex-MapTools-Converter-$version-src.zip"
if [[ ! -f "$generated_source_archive" ]]; then
    echo "Quellpaket wurde nicht erzeugt: $generated_source_archive" >&2
    exit 1
fi
cp "$generated_source_archive" "$source_release_directory/"
portable_parent="$build_directory/desktopApp/compose/binaries/main/app"
portable_name="ArxSilex MapTools Converter"
cp "$project_root/LICENSE" "$portable_parent/$portable_name/LICENSE"
cp "$project_root/NOTICE.md" "$portable_parent/$portable_name/NOTICE.md"
portable_archive="$linux_release_directory/ArxSilex-MapTools-Converter-$version-linux-x64.tar.gz"
archive_temporary_directory="$linux_root/.release-temp"
archive_temporary_tar="$archive_temporary_directory/linux-$version-$$.tar"
cleanup_archive_temporary_file() {
    rm -f -- "$archive_temporary_tar"
    rmdir "$archive_temporary_directory" 2>/dev/null || true
}
trap cleanup_archive_temporary_file EXIT INT TERM
mkdir -p "$archive_temporary_directory"
tar \
    --owner=0 --group=0 --numeric-owner \
    --mode='a-x,a+X,u+rw,go+r,go-w' \
    --exclude="$portable_name/bin/$portable_name" \
    --exclude="$portable_name/bin/maptools-worker" \
    -C "$portable_parent" -cf "$archive_temporary_tar" "$portable_name"
tar \
    --owner=0 --group=0 --numeric-owner \
    --mode='u=rwx,go=rx' \
    -C "$portable_parent" -rf "$archive_temporary_tar" \
    "$portable_name/bin/$portable_name" \
    "$portable_name/bin/maptools-worker"
gzip -n -c "$archive_temporary_tar" > "$portable_archive"
cleanup_archive_temporary_file
trap - EXIT INT TERM

generated_sbom="$build_directory/root/reports/cyclonedx/bom.json"
if [[ ! -f "$generated_sbom" ]]; then
    echo "CycloneDX-SBOM wurde nicht erzeugt: $generated_sbom" >&2
    exit 1
fi
sbom_name="ArxSilex-MapTools-Converter-$version-linux-x64.cdx.json"
cp "$generated_sbom" "$security_report_directory/$sbom_name"
cp "$generated_sbom" "$security_release_directory/$sbom_name"

{
    # Record the kernel and architecture without exposing the local host name.
    uname -srmo
    "$JAVA_HOME/bin/java" -version
    bash "$project_root/application/gradlew" -p "$project_root/application" --no-daemon --version |
        sed -E 's#^Daemon JVM:.*#Daemon JVM: project-local JDK (see Java version above)#'
    if [[ -n "${MAPTOOLS_DRVFS_CHMOD_SHIM:-}" ]]; then
        printf 'DrvFS compatibility SHA-256: '
        sha256sum "$MAPTOOLS_DRVFS_CHMOD_SHIM" | awk '{ print $1 }'
    fi
} > "$security_report_directory/toolchain-linux.txt" 2>&1
cp "$security_report_directory/toolchain-linux.txt" "$security_release_directory/toolchain-linux.txt"

echo "Linux-Veröffentlichung erzeugt: $release_directory"
