#!/bin/bash
set -euo pipefail

# c65gm Release Builder
#
# Fully automated release process:
#   1. Verifies git working tree is clean
#   2. Reads BUILDNUM, derives version (MAJOR.BUILDNUM)
#   3. Verifies the tag doesn't already exist
#   4. Bumps BUILDNUM
#   5. Builds all target binaries (embedded lib, version injected)
#   6. Generates SHA256 checksums
#   7. Commits the BUILDNUM bump (with checksums in commit body)
#   8. Creates an annotated tag pointing at PRE-bump commit
#      (tag message contains checksums + build info for verification)
#
# To publish the release:
#   git push --follow-tags origin

MAJOR=1

print_ok()   { echo "  [OK] $1"; }
print_err()  { echo "  [ERROR] $1" >&2; }

echo ""
echo "=== c65gm Release Builder ==="
echo ""

# ---------------------------------------------------------------------------
# 1. Verify git working tree is clean
# ---------------------------------------------------------------------------
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
    echo ""
    git status --short
    echo ""
    print_err "working tree is not clean — commit or stash changes first"
    exit 1
fi
print_ok "Working tree is clean"

# ---------------------------------------------------------------------------
# 2. Read BUILDNUM
# ---------------------------------------------------------------------------
if [ ! -f BUILDNUM ]; then
    echo "1" > BUILDNUM
fi

BUILDNUM=$(cat BUILDNUM)
VERSION="${MAJOR}.${BUILDNUM}"
TAG="v${VERSION}"

# ---------------------------------------------------------------------------
# 3. Verify tag doesn't already exist
# ---------------------------------------------------------------------------
if git rev-parse --quiet --verify "refs/tags/${TAG}" >/dev/null 2>&1; then
    print_err "tag ${TAG} already exists — bump BUILDNUM manually if needed"
    exit 1
fi
print_ok "Tag ${TAG} is available"

# ---------------------------------------------------------------------------
# 4. Save source commit (before any changes)
# ---------------------------------------------------------------------------
SOURCE_COMMIT=$(git rev-parse HEAD)
if [ -z "$SOURCE_COMMIT" ]; then
    print_err "could not determine HEAD commit"
    exit 1
fi

echo ""
echo "  Version:     ${TAG}"
echo "  Source:      ${SOURCE_COMMIT}"
echo "  BUILDNUM:    ${BUILDNUM} (bumps to $((BUILDNUM + 1)))"
echo ""

# ---------------------------------------------------------------------------
# 5. Bump BUILDNUM
# ---------------------------------------------------------------------------
NEXT_BUILDNUM=$((BUILDNUM + 1))
echo "${NEXT_BUILDNUM}" > BUILDNUM

# ---------------------------------------------------------------------------
# 6. Copy lib for embedding
# ---------------------------------------------------------------------------
echo "  Preparing embedded library..."
rm -rf internal/preproc/lib
cp -r lib internal/preproc/
print_ok "Library copied for embedding"

# ---------------------------------------------------------------------------
# Build metadata
# ---------------------------------------------------------------------------
GO_VERSION="$(go version 2>/dev/null || echo 'unknown')"
BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +%Y-%m-%d)"

LDFLAGS="-s -w -X main.version=${VERSION}"
DIST="dist"
rm -rf "$DIST"
mkdir -p "$DIST"

# SHA256 command detection (Linux vs macOS)
SHA_CMD=""
if command -v sha256sum &>/dev/null; then
    SHA_CMD="sha256sum"
elif command -v shasum &>/dev/null; then
    SHA_CMD="shasum -a 256"
else
    print_err "no sha256sum or shasum command found"
    exit 1
fi

# Targets
TARGETS=(
    "linux/amd64"
    "linux/arm64"
    "darwin/amd64"
    "darwin/arm64"
    "windows/amd64"
)

echo ""
echo "  Building targets: ${TARGETS[*]}"
echo ""

# ---------------------------------------------------------------------------
# 7. Build all targets
# ---------------------------------------------------------------------------
BUILD_DIR="$(mktemp -d)"
trap 'rm -rf "$BUILD_DIR"' EXIT

for target in "${TARGETS[@]}"; do
    GOOS="${target%%/*}"
    GOARCH="${target##*/}"

    bin_name="c65gm"
    [ "$GOOS" = "windows" ] && bin_name="c65gm.exe"

    echo "    ${target}..."

    GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=0 \
        go build -trimpath -ldflags="$LDFLAGS" -o "${BUILD_DIR}/${bin_name}"

    archive_name="c65gm_v${VERSION}_${GOOS}_${GOARCH}"
    if [ "$GOOS" = "windows" ]; then
        (cd "$BUILD_DIR" && zip -q "${OLDPWD}/${DIST}/${archive_name}.zip" "$bin_name")
        echo "      => ${DIST}/${archive_name}.zip"
    else
        tar -czf "${DIST}/${archive_name}.tar.gz" -C "$BUILD_DIR" "$bin_name"
        echo "      => ${DIST}/${archive_name}.tar.gz"
    fi

    rm -f "${BUILD_DIR}/${bin_name}"
done

echo ""
print_ok "All targets built"

# ---------------------------------------------------------------------------
# 8. Generate checksums
# ---------------------------------------------------------------------------
echo ""
echo "=== SHA256 checksums ==="
echo ""
(
    cd "$DIST"
    $SHA_CMD * > checksums.txt
    cat checksums.txt
)

CHECKSUMS_TEXT="$(cat "${DIST}/checksums.txt")"
print_ok "Checksums generated"

# ---------------------------------------------------------------------------
# 9. Commit BUILDNUM bump
# ---------------------------------------------------------------------------
echo ""
echo "=== Creating commit ==="

COMMIT_MSG=$(cat << COMMIT_EOF
${TAG}

Built with: ${GO_VERSION}
Build date: ${BUILD_DATE}

SHA256 checksums:
${CHECKSUMS_TEXT}
COMMIT_EOF
)

git add BUILDNUM
git commit -m "$COMMIT_MSG"
print_ok "Commit created (BUILDNUM bumped to ${NEXT_BUILDNUM})"

# ---------------------------------------------------------------------------
# 10. Create annotated tag pointing at source commit
# ---------------------------------------------------------------------------
echo ""
echo "=== Creating tag ==="

TAG_MSG=$(cat << TAG_EOF
c65gm ${TAG}

Built with: ${GO_VERSION}
Build date: ${BUILD_DATE}

SHA256 checksums:
${CHECKSUMS_TEXT}

To reproduce this build:
  git checkout ${TAG}
  go build -trimpath -ldflags="${LDFLAGS}"

Then verify:
  sha256sum c65gm
TAG_EOF
)

git tag -a "$TAG" "$SOURCE_COMMIT" -m "$TAG_MSG"
print_ok "Tag ${TAG} created (pointing at ${SOURCE_COMMIT})"

# ---------------------------------------------------------------------------
# 11. Summary
# ---------------------------------------------------------------------------
echo ""
echo "============================================"
echo "  c65gm ${TAG} released!"
echo ""
echo "  Source commit:  ${SOURCE_COMMIT}"
echo "  BUILDNUM:       ${BUILDNUM} → ${NEXT_BUILDNUM}"
echo "  Artifacts in:   ${DIST}/"
echo "  Go version:     ${GO_VERSION}"
echo ""
echo "  !!! IMPORTANT !!!"
echo "  The tag '${TAG}' exists ONLY on your machine."
echo "  It must be pushed separately to make it available."
echo ""
echo "  To publish the complete release:"
echo "    git push --follow-tags origin"
echo ""
echo "  If you already pushed without --follow-tags:"
echo "    git push origin ${TAG}"
echo ""
echo "  Artifacts:"
ls -lh "${DIST}/" | sed 's/^/    /'
echo "============================================"
echo ""
