#!/usr/bin/env bash
# Release script - creates a new release.
#
# This script:
# 1. Runs all release checks
# 2. Merges dev → main (if on dev)
# 3. Creates a signed git tag
# 4. Generates SBOM
# 5. Builds and optionally publishes to PyPI
#
# Usage:
#   ./scripts/release [VERSION] [--dry-run] [--no-publish]
#
# Arguments:
#   VERSION      Version to release (default: read from pyproject.toml)
#   --dry-run    Show what would happen without making changes
#   --no-publish Skip PyPI upload (just tag and build)
#
# Environment:
#   PYPI_TOKEN   API token for PyPI upload (or use keyring)
#   GPG_KEY_ID   GPG key for signing (optional, uses default if not set)
#
set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

DRY_RUN=false
NO_PUBLISH=false
VERSION=""

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        --no-publish)
            NO_PUBLISH=true
            shift
            ;;
        -*)
            echo "Unknown option: $1"
            exit 1
            ;;
        *)
            VERSION="$1"
            shift
            ;;
    esac
done

# Get project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"

# Get version from pyproject.toml if not provided
if [[ -z "$VERSION" ]]; then
    VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
fi

if [[ -z "$VERSION" ]]; then
    echo -e "${RED}Error: Could not determine version${NC}"
    exit 1
fi

echo "╔════════════════════════════════════════╗"
echo "║          Release v$VERSION"
echo "╚════════════════════════════════════════╝"
echo ""

if $DRY_RUN; then
    echo -e "${YELLOW}[DRY RUN MODE - no changes will be made]${NC}"
    echo ""
fi

run() {
    if $DRY_RUN; then
        echo -e "${BLUE}[dry-run]${NC} $*"
    else
        "$@"
    fi
}

# ─────────────────────────────────────────────────────────────
echo "━━━ Step 1: Pre-release checks ━━━"
# ─────────────────────────────────────────────────────────────

if ! ./scripts/release-check; then
    echo -e "${RED}Release checks failed. Aborting.${NC}"
    exit 1
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 2: Branch management ━━━"
# ─────────────────────────────────────────────────────────────

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

if [[ "$CURRENT_BRANCH" == "dev" ]]; then
    echo "On dev branch - will merge to main"

    # Ensure main is up to date
    run git fetch origin main

    # Switch to main and merge
    run git checkout main
    run git pull origin main
    run git merge dev --no-ff -m "Release v$VERSION"

elif [[ "$CURRENT_BRANCH" == "main" ]]; then
    echo "Already on main branch"
else
    echo -e "${YELLOW}Warning: On branch '$CURRENT_BRANCH', expected 'dev' or 'main'${NC}"
    read -p "Continue anyway? [y/N] " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 3: Create signed tag ━━━"
# ─────────────────────────────────────────────────────────────

TAG="v$VERSION"

if git rev-parse "$TAG" >/dev/null 2>&1; then
    echo -e "${RED}Tag $TAG already exists!${NC}"
    exit 1
fi

# Create annotated, signed tag
GPG_KEY="${GPG_KEY_ID:-}"
if [[ -n "$GPG_KEY" ]]; then
    run git tag -s -u "$GPG_KEY" "$TAG" -m "Release $TAG"
else
    # Try to sign with default key, fall back to annotated tag
    if git config --get user.signingkey >/dev/null 2>&1; then
        run git tag -s "$TAG" -m "Release $TAG"
    else
        echo -e "${YELLOW}Warning: No GPG key configured, creating unsigned tag${NC}"
        run git tag -a "$TAG" -m "Release $TAG"
    fi
fi

echo -e "${GREEN}Created tag: $TAG${NC}"

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 4: Build artifacts ━━━"
# ─────────────────────────────────────────────────────────────

# Clean previous builds
rm -rf dist/ build/ *.egg-info

# Build wheel and sdist
run python -m build

# List what was built
echo "Built artifacts:"
ls -la dist/

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 5: Generate checksums ━━━"
# ─────────────────────────────────────────────────────────────

if ! $DRY_RUN; then
    cd dist
    sha256sum * > SHA256SUMS
    cat SHA256SUMS
    cd ..
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 6: Generate SBOM ━━━"
# ─────────────────────────────────────────────────────────────

if command -v cyclonedx-py &>/dev/null; then
    run cyclonedx-py environment -o dist/sbom.json --format json
    echo "SBOM generated: dist/sbom.json"
elif command -v pip-audit &>/dev/null; then
    # Fallback: generate a simple dependency list
    run pip-audit --format json > dist/dependencies.json 2>/dev/null || true
    echo "Dependency audit saved: dist/dependencies.json"
else
    echo -e "${YELLOW}Warning: No SBOM generator installed (install cyclonedx-bom)${NC}"
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 7: Push to remote ━━━"
# ─────────────────────────────────────────────────────────────

echo "Pushing main branch and tag..."
run git push origin main
run git push origin "$TAG"

# If we merged from dev, also push updated dev
if [[ "$CURRENT_BRANCH" == "dev" ]]; then
    run git checkout dev
    run git merge main --ff-only
    run git push origin dev
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "━━━ Step 8: Publish to PyPI ━━━"
# ─────────────────────────────────────────────────────────────

if $NO_PUBLISH; then
    echo -e "${YELLOW}Skipping PyPI publish (--no-publish)${NC}"
else
    if [[ -n "${PYPI_TOKEN:-}" ]]; then
        echo "Publishing to PyPI..."
        run python -m twine upload dist/*.whl dist/*.tar.gz
    else
        echo -e "${YELLOW}PYPI_TOKEN not set - skipping publish${NC}"
        echo "To publish manually:"
        echo "  PYPI_TOKEN=your-token twine upload dist/*"
    fi
fi

# ─────────────────────────────────────────────────────────────
echo ""
echo "╔════════════════════════════════════════╗"
echo -e "║  ${GREEN}Release v$VERSION complete!${NC}            ║"
echo "╚════════════════════════════════════════╝"
echo ""
echo "Artifacts in dist/:"
ls dist/
echo ""
echo "Next steps:"
echo "  1. Create GitHub/Codeberg release with dist/* artifacts"
echo "  2. Update release notes"
echo "  3. Announce release"
