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

# ─────────────────────────────────────────────────────────────────────────────
# release.sh — build release binaries and package tarballs for fafb-q.
#
# Usage:
#   ./scripts/release.sh [options]
#
# Options:
#   --target <triple>   Build a single target (e.g., x86_64-unknown-linux-musl)
#   --all               Build all targets appropriate for the host OS
#   --version <ver>     Version string for artifact naming (default: git tag or dev-<sha>)
#   --output <dir>      Output directory for tarballs (default: target/release-artifacts)
#
# Targets:
#   macOS (local only):
#     x86_64-apple-darwin
#     aarch64-apple-darwin
#   Linux (local via cross, or native in CI):
#     x86_64-unknown-linux-musl
#     aarch64-unknown-linux-musl
#
# Examples:
#   ./scripts/release.sh --all
#   ./scripts/release.sh --target x86_64-unknown-linux-musl
#   ./scripts/release.sh --all --version v1.0.0
# ─────────────────────────────────────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

MACOS_TARGETS=(
    "x86_64-apple-darwin"
    "aarch64-apple-darwin"
)
LINUX_TARGETS=(
    "x86_64-unknown-linux-musl"
    "aarch64-unknown-linux-musl"
)

BINARY_NAME="fafb-q"
VERSION=""
OUTPUT_DIR=""
BUILD_TARGETS=()
HOST_OS="$(uname -s)"

# ── Helpers ──────────────────────────────────────────────────────────────────

die() { echo "ERROR: $*" >&2; exit 1; }

detect_version() {
    if [[ -n "$VERSION" ]]; then
        return
    fi
    # Try git tag on HEAD
    local tag
    tag="$(git -C "$PROJECT_DIR" describe --tags --exact-match HEAD 2>/dev/null || true)"
    if [[ -n "$tag" ]]; then
        VERSION="$tag"
    else
        local sha
        sha="$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")"
        VERSION="dev-${sha}"
    fi
}

check_cross() {
    if ! command -v cross &>/dev/null; then
        die "'cross' is not installed. Install with: cargo install cross"
    fi
    if ! command -v docker &>/dev/null && ! command -v podman &>/dev/null; then
        die "'cross' requires Docker or Podman to be installed and running."
    fi
}

needs_cross() {
    local target="$1"
    case "$HOST_OS" in
        Darwin)
            # macOS host: need cross for Linux targets
            [[ "$target" == *"-linux-"* ]]
            ;;
        Linux)
            # Linux host: need cross for macOS targets (unlikely, but handle it)
            [[ "$target" == *"-apple-"* ]]
            ;;
    esac
}

ensure_target() {
    local target="$1"
    if ! needs_cross "$target"; then
        rustup target add "$target" 2>/dev/null || true
    fi
}

build_target() {
    local target="$1"

    echo "────────────────────────────────────────────────"
    echo "  Building: $target"
    echo "────────────────────────────────────────────────"

    ensure_target "$target"

    if needs_cross "$target"; then
        check_cross
        cross build --release --target "$target" --manifest-path "$PROJECT_DIR/Cargo.toml"
    else
        cargo build --release --target "$target" --manifest-path "$PROJECT_DIR/Cargo.toml"
    fi
}

package_target() {
    local target="$1"
    local binary_path="$PROJECT_DIR/target/${target}/release/${BINARY_NAME}"
    local artifact_name="${BINARY_NAME}-${VERSION}-${target}"
    local staging_dir="$OUTPUT_DIR/${artifact_name}"
    local tarball="$OUTPUT_DIR/${artifact_name}.tar.gz"

    if [[ ! -f "$binary_path" ]]; then
        die "Binary not found at $binary_path — build may have failed."
    fi

    echo "  Packaging: ${artifact_name}.tar.gz"

    rm -rf "$staging_dir"
    mkdir -p "$staging_dir"

    cp "$binary_path" "$staging_dir/${BINARY_NAME}"
    cp "$PROJECT_DIR/config/config.example.toml" "$staging_dir/config.example.toml"

    tar -czf "$tarball" -C "$OUTPUT_DIR" "$artifact_name"
    rm -rf "$staging_dir"

    echo "  Created:   $tarball"
}

# ── Parse arguments ──────────────────────────────────────────────────────────

while [[ $# -gt 0 ]]; do
    case "$1" in
        --target)
            BUILD_TARGETS+=("$2"); shift 2 ;;
        --all)
            shift ;;
        --version)
            VERSION="$2"; shift 2 ;;
        --output)
            OUTPUT_DIR="$2"; shift 2 ;;
        -h|--help)
            sed -n '/^# Usage:/,/^# ──/p' "$0" | sed '$d' | sed 's/^# //' | sed 's/^#//'
            exit 0 ;;
        *)
            die "Unknown option: $1" ;;
    esac
done

# If no specific targets, build all for this host
if [[ ${#BUILD_TARGETS[@]} -eq 0 ]]; then
    case "$HOST_OS" in
        Darwin)
            BUILD_TARGETS=("${MACOS_TARGETS[@]}" "${LINUX_TARGETS[@]}")
            ;;
        Linux)
            BUILD_TARGETS=("${LINUX_TARGETS[@]}")
            ;;
        *)
            die "Unsupported host OS: $HOST_OS"
            ;;
    esac
fi

detect_version
OUTPUT_DIR="${OUTPUT_DIR:-$PROJECT_DIR/target/release-artifacts}"
mkdir -p "$OUTPUT_DIR"

echo "================================================"
echo "  fafb-q release build"
echo "  Version:  $VERSION"
echo "  Host:     $HOST_OS"
echo "  Targets:  ${BUILD_TARGETS[*]}"
echo "  Output:   $OUTPUT_DIR"
echo "================================================"
echo ""

# ── Build and package ────────────────────────────────────────────────────────

for target in "${BUILD_TARGETS[@]}"; do
    build_target "$target"
    package_target "$target"
    echo ""
done

# ── Summary ──────────────────────────────────────────────────────────────────

echo "================================================"
echo "  Release artifacts:"
echo "================================================"
for target in "${BUILD_TARGETS[@]}"; do
    local_tarball="$OUTPUT_DIR/${BINARY_NAME}-${VERSION}-${target}.tar.gz"
    if [[ -f "$local_tarball" ]]; then
        size="$(du -h "$local_tarball" | cut -f1)"
        echo "  $size  $(basename "$local_tarball")"
    fi
done
echo ""
echo "Done."
