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

# FURNACE Release Script
# Builds binaries for all platforms, creates GitHub Release, uploads artifacts,
# and syncs everything to the furnace-releases distribution repo.
#
# Build strategy:
#   - macOS ARM:   native cargo build (fastest)
#   - Linux x64:   Docker container with full Rust toolchain + protoc
#   - Windows x64: Docker container with mingw cross-compilation
#
# Note: macOS Intel (x86_64) is not built separately — ARM binaries run
# on Intel Macs via Rosetta 2.
#
# Prerequisites:
#   brew install gh
#   gh auth login
#   Docker must be running (for Linux/Windows builds)
#
# First-time Docker image setup (run once):
#   docker build --platform linux/amd64 -t furnace-build-linux -f docker/Dockerfile.build-linux .
#   docker build --platform linux/amd64 -t furnace-build-windows -f docker/Dockerfile.build-windows .
#
# The furnace-releases repo must be cloned as a sibling:
#   git clone git@github-forgewithfurnace:forgewithfurnace/furnace-releases.git ../furnace-releases
#
# Usage:
#   ./scripts/release.sh              # Uses version from Cargo.toml
#   ./scripts/release.sh 0.2.0        # Override version

VERSION="${1:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')}"
TAG="v${VERSION}"
DIST="target/dist"
RELEASES_REPO="$(cd "$(dirname "$0")/.." && pwd)/../furnace-releases"

echo "=== FURNACE Release ${TAG} ==="
echo ""

# Verify tools
for cmd in cargo gh docker; do
    if ! command -v "$cmd" &>/dev/null; then
        echo "ERROR: $cmd not found. Install it first."
        exit 1
    fi
done

# Verify gh auth
if ! gh auth status &>/dev/null; then
    echo "ERROR: gh not authenticated. Run: gh auth login"
    exit 1
fi

# Verify Docker is running
if ! docker info &>/dev/null; then
    echo "ERROR: Docker is not running. Start Docker Desktop first."
    exit 1
fi

# Verify Docker images exist
for img in furnace-build-linux furnace-build-windows; do
    if ! docker image inspect "$img" &>/dev/null; then
        echo "ERROR: Docker image '$img' not found."
        echo "Build it first: docker build --platform linux/amd64 -t $img -f docker/Dockerfile.build-${img#furnace-build-} ."
        exit 1
    fi
done

# Verify furnace-releases repo exists
if [ ! -d "${RELEASES_REPO}/.git" ]; then
    echo "ERROR: furnace-releases repo not found at ${RELEASES_REPO}"
    echo "Clone it: git clone git@github-forgewithfurnace:forgewithfurnace/furnace-releases.git ${RELEASES_REPO}"
    exit 1
fi

# Clean dist directory
rm -rf "${DIST}"
mkdir -p "${DIST}"

# --- macOS ARM (native) ---
echo "--- Building aarch64-apple-darwin (native) ---"
cargo build --release --target aarch64-apple-darwin
tar czf "${DIST}/furnace-aarch64-apple-darwin.tar.gz" -C target/aarch64-apple-darwin/release furnace
echo "  Done: $(du -h "${DIST}/furnace-aarch64-apple-darwin.tar.gz" | cut -f1)"
echo ""

# --- Linux x64 (Docker with thin LTO) ---
echo "--- Building x86_64-unknown-linux-gnu (Docker) ---"
docker run --rm --platform linux/amd64 \
    -v "$(pwd)":/build/furnace \
    -w /build/furnace \
    -e CARGO_PROFILE_RELEASE_LTO=thin \
    furnace-build-linux \
    cargo build --release --target x86_64-unknown-linux-gnu --locked
tar czf "${DIST}/furnace-x86_64-unknown-linux-gnu.tar.gz" -C target/x86_64-unknown-linux-gnu/release furnace
echo "  Done: $(du -h "${DIST}/furnace-x86_64-unknown-linux-gnu.tar.gz" | cut -f1)"
echo ""

# --- Windows x64 (Docker with thin LTO) ---
echo "--- Building x86_64-pc-windows-gnu (Docker) ---"
docker run --rm --platform linux/amd64 \
    -v "$(pwd)":/build/furnace \
    -w /build/furnace \
    -e CARGO_PROFILE_RELEASE_LTO=thin \
    furnace-build-windows \
    cargo build --release --target x86_64-pc-windows-gnu --locked
(cd target/x86_64-pc-windows-gnu/release && zip -q "../../../${DIST}/furnace-x86_64-pc-windows-gnu.zip" furnace.exe)
echo "  Done: $(du -h "${DIST}/furnace-x86_64-pc-windows-gnu.zip" | cut -f1)"
echo ""

echo "=== All builds complete ==="
ls -lh "${DIST}/"
echo ""

# --- Package VS Code extension ---
VSCODE_DIR="$(cd "$(dirname "$0")/.." && pwd)/../furnace-vscode"
if [ -d "${VSCODE_DIR}" ]; then
    echo "--- Packaging VS Code extension ---"
    (cd "${VSCODE_DIR}" && npx @vscode/vsce package --no-dependencies -o "${VSCODE_DIR}/furnace-forge-project-${VERSION}.vsix")
    echo "  Done: $(du -h "${VSCODE_DIR}/furnace-forge-project-${VERSION}.vsix" | cut -f1)"
    echo ""
fi

# --- Package IntelliJ plugin ---
INTELLIJ_DIR="$(cd "$(dirname "$0")/.." && pwd)/../furnace-intellij"
if [ -d "${INTELLIJ_DIR}" ]; then
    echo "--- Packaging IntelliJ plugin ---"
    (cd "${INTELLIJ_DIR}" && ./gradlew buildPlugin -q)
    echo "  Done: $(ls -lh "${INTELLIJ_DIR}/build/distributions/"*.zip | awk '{print $5}')"
    echo ""
fi

# --- Copy extension artifacts to furnace-releases repo ---
echo "--- Copying extension artifacts to furnace-releases ---"
mkdir -p "${RELEASES_REPO}/extensions/vscode"
mkdir -p "${RELEASES_REPO}/extensions/intellij"

VSCODE_VSIX="${VSCODE_DIR}/furnace-forge-project-${VERSION}.vsix"
if [ -f "${VSCODE_VSIX}" ]; then
    cp "${VSCODE_VSIX}" "${RELEASES_REPO}/extensions/vscode/"
    echo "  Copied VS Code extension: $(basename "${VSCODE_VSIX}")"
fi

INTELLIJ_ZIP="${INTELLIJ_DIR}/build/distributions/furnace-intellij-${VERSION}.zip"
if [ -f "${INTELLIJ_ZIP}" ]; then
    cp "${INTELLIJ_ZIP}" "${RELEASES_REPO}/extensions/intellij/"
    echo "  Copied IntelliJ plugin: $(basename "${INTELLIJ_ZIP}")"
fi

# Commit extension artifacts to furnace-releases
(
    cd "${RELEASES_REPO}"
    git pull --rebase origin main 2>/dev/null || true
    git add extensions/
    if ! git diff --cached --quiet; then
        git commit -m "chore: add ${TAG} extension artifacts (VS Code + IntelliJ)"
        git push origin main
        echo "  Extension artifacts pushed to furnace-releases"
    else
        echo "  No new extension artifacts to commit"
    fi
)
echo ""

# --- Update version strings in READMEs ---
echo "--- Updating version strings in READMEs ---"

# Update furnace/README.md
sed -i '' "s/# furnace [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/# furnace ${VERSION}/" README.md
echo "  Updated furnace/README.md"

# Update smithery.yaml version
sed -i '' "s/^version: [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/version: ${VERSION}/" smithery.yaml
echo "  Updated smithery.yaml"

# Update furnace-releases/README.md
sed -i '' "s/furnace-forge-project-[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/furnace-forge-project-${VERSION}/g" "${RELEASES_REPO}/README.md"
sed -i '' "s/| FURNACE MCP Server | [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* |/| FURNACE MCP Server | ${VERSION} |/" "${RELEASES_REPO}/README.md"
sed -i '' "s/| VS Code Extension | [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* |/| VS Code Extension | ${VERSION} |/" "${RELEASES_REPO}/README.md"
sed -i '' "s/| IntelliJ Plugin | [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* |/| IntelliJ Plugin | ${VERSION} |/" "${RELEASES_REPO}/README.md"
echo "  Updated furnace-releases/README.md"

# Commit version updates in furnace repo (will be included in the tag)
git add README.md smithery.yaml
if ! git diff --cached --quiet; then
    git commit -m "chore: update README and smithery versions to ${VERSION}"
fi

# Commit README updates in furnace-releases repo
(
    cd "${RELEASES_REPO}"
    git add README.md
    if ! git diff --cached --quiet; then
        git commit -m "chore: update README versions to ${VERSION}"
        git push origin main
    fi
)
echo ""

# Create git tag (delete existing if re-releasing)
if git rev-parse "$TAG" &>/dev/null; then
    echo "Deleting existing tag ${TAG}..."
    git tag -d "$TAG"
    git push origin --delete "$TAG" 2>/dev/null || true
fi
echo "Creating tag ${TAG}..."
git tag "$TAG"
git push origin "$TAG"

# Create GitHub Release on furnace-releases repo (binaries only)
echo ""
echo "Creating GitHub Release ${TAG} on furnace-releases..."

# Pull latest furnace-releases
(cd "${RELEASES_REPO}" && git pull --rebase origin main 2>/dev/null || true)

# Delete existing release + tag on furnace-releases (if re-releasing)
echo "Cleaning up previous release ${TAG} (if any)..."
gh release delete "$TAG" --repo forgewithfurnace/furnace-releases --yes 2>/dev/null || true
(
    cd "${RELEASES_REPO}"
    if git rev-parse "$TAG" &>/dev/null; then
        echo "Deleting existing tag ${TAG} in furnace-releases..."
        git tag -d "$TAG"
        git push origin --delete "$TAG" 2>/dev/null || true
    fi
    git tag "$TAG"
    git push origin "$TAG"
)

# Write release notes to a temp file (avoids heredoc quoting issues)
NOTES_FILE=$(mktemp)
cat > "${NOTES_FILE}" <<NOTES_EOF
## FURNACE ${VERSION}

### Installation

**Via npm (recommended):**
\`\`\`bash
npm install -g furnace-mcp
\`\`\`

**MCP client config (Claude Code / Claude Desktop):**
\`\`\`json
{"mcpServers": {"furnace": {"command": "npx", "args": ["-y", "furnace-mcp"]}}}
\`\`\`

**Pre-built binaries** (download below):
\`\`\`bash
# macOS (Apple Silicon — also runs on Intel via Rosetta 2)
curl -L https://github.com/forgewithfurnace/furnace-releases/releases/download/${TAG}/furnace-aarch64-apple-darwin.tar.gz | tar xz
sudo mv furnace /usr/local/bin/

# Linux (x86_64)
curl -L https://github.com/forgewithfurnace/furnace-releases/releases/download/${TAG}/furnace-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv furnace /usr/local/bin/

# Windows (x86_64) — download and extract the .zip, add to PATH
\`\`\`

**From crates.io:**
\`\`\`bash
cargo install furnace-mcp
\`\`\`

### What's New in ${VERSION}

- **Fix: no more unwanted .furnace/ directories** — informational tools (furnace_status, get_metrics, list_scrolls, list_recipes, list_connections) now return pre-init responses without triggering project initialization
- **Fix: reverted IDE icons to native SVGs** — VS Code monochrome icon and IntelliJ vector icons restored
- **Lazy init guard**: .furnace/ is only created when you explicitly use scroll, search, or analysis tools
- 594 tests passing, 28 MCP tools, 9 AI agents
NOTES_EOF

gh release create "$TAG" \
    --repo forgewithfurnace/furnace-releases \
    --title "FURNACE ${TAG}" \
    --notes-file "${NOTES_FILE}" \
    "${DIST}"/*.tar.gz \
    "${DIST}"/*.zip

rm -f "${NOTES_FILE}"

echo ""
echo "=== Release ${TAG} published ==="
echo "https://github.com/forgewithfurnace/furnace-releases/releases/tag/${TAG}"

# --- Publish to crates.io ---
echo "--- Publishing to crates.io ---"
if cargo publish --dry-run 2>/dev/null; then
    cargo publish
    echo "  Published furnace-mcp ${VERSION} to crates.io"
else
    echo "  WARNING: cargo publish dry-run failed. Publish manually: cargo publish"
fi
echo ""

# --- Publish to npm ---
NPM_DIR="$(cd "$(dirname "$0")/.." && pwd)/../furnace-npm"
if [ -d "${NPM_DIR}" ]; then
    echo "--- Publishing to npm ---"
    # Update version in furnace-npm/package.json
    sed -i '' "s/\"version\": \"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\"/\"version\": \"${VERSION}\"/" "${NPM_DIR}/package.json"
    (
        cd "${NPM_DIR}"
        git add package.json
        if ! git diff --cached --quiet; then
            git commit -m "chore: bump version to ${VERSION}"
            git push origin master
        fi
        npm publish
        echo "  Published furnace-mcp ${VERSION} to npm"
    )
else
    echo "  WARNING: furnace-npm repo not found at ${NPM_DIR}. Publish manually."
fi
echo ""

echo "=== All done ==="
echo "GitHub Release: https://github.com/forgewithfurnace/furnace-releases/releases/tag/${TAG}"
echo "crates.io: https://crates.io/crates/furnace-mcp"
echo "npm: https://www.npmjs.com/package/furnace-mcp"
