#!/bin/zsh

set -e

# A `realpath` alternative using the default C implementation.
filepath() {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

# Capture script name for usage display
SCRIPT_NAME="$(basename "$0")"

# Usage function
show_usage() {
  cat << EOF
Usage: $SCRIPT_NAME [branch] [--force] [--help]

Automated script to update DarwinPrivateFrameworks with AttributeGraph changes.

Arguments:
  branch          Target branch to generate from (default: current branch)

Options:
  --force         Force push the branch when creating PR
  --help          Show this help message

Examples:
  $SCRIPT_NAME                    # Update from current branch
  $SCRIPT_NAME develop            # Update from develop branch
  $SCRIPT_NAME main --force       # Update from main with force push
  $SCRIPT_NAME --help             # Show this help

Description:
  This script automates the process of updating DarwinPrivateFrameworks
  with the latest AttributeGraph changes by:
  1. Setting up a git worktree for the target branch (if not current branch)
  2. Cloning DarwinPrivateFrameworks repository
  3. Generating AG template from OpenAttributeGraph
  4. Updating headers and Swift interface templates
  5. Creating and pushing a PR with the changes
EOF
}

# Parse command line arguments
TARGET_BRANCH=""
FORCE_PUSH=""

# Parse arguments
while [[ $# -gt 0 ]]; do
  case $1 in
    --help)
      show_usage
      exit 0
      ;;
    --force)
      FORCE_PUSH="--force"
      shift
      ;;
    *)
      TARGET_BRANCH="$1"
      shift
      ;;
  esac
done

SCRIPT_ROOT="$(dirname $(dirname $(filepath $0)))"

# Get current branch if no target branch specified
if [[ -z "$TARGET_BRANCH" ]]; then
  cd "$SCRIPT_ROOT"
  TARGET_BRANCH="$(git branch --show-current)"
  if [[ -z "$TARGET_BRANCH" ]]; then
    echo "Error: Could not determine current branch and no branch specified"
    exit 1
  fi
fi

OAG_REPO_DIR="$SCRIPT_ROOT/.oag_repo"
OPENATTRIBUTEGRAPH_ROOT="$OAG_REPO_DIR"
AG_REPO_DIR="$SCRIPT_ROOT/.ag_repo"

# Check if we're already on the target branch
cd "$SCRIPT_ROOT"
CURRENT_BRANCH="$(git branch --show-current)"
USE_WORKTREE=true
if [[ "$CURRENT_BRANCH" == "$TARGET_BRANCH" ]]; then
  USE_WORKTREE=false
  OPENATTRIBUTEGRAPH_ROOT="$SCRIPT_ROOT"
fi

echo "Starting DarwinPrivateFrameworks bump PR workflow..."
echo "Target branch: $TARGET_BRANCH"
if [[ -n "$FORCE_PUSH" ]]; then
  echo "Force push: enabled"
fi

# Cleanup function
cleanup() {
  if [[ -d "$AG_REPO_DIR" ]]; then
    echo "Cleaning up temporary repository..."
    rm -rf "$AG_REPO_DIR"
  fi
  if [[ "$USE_WORKTREE" == true ]] && [[ -d "$OAG_REPO_DIR" ]]; then
    echo "Cleaning up git worktree..."
    cd "$SCRIPT_ROOT"
    git worktree remove --force "$OAG_REPO_DIR" 2>/dev/null || true
  fi
}

# Set trap to cleanup on exit
trap cleanup EXIT

cd "$SCRIPT_ROOT"

# Step 1: Setup git worktree for target branch (if needed)
if [[ "$USE_WORKTREE" == true ]]; then
  echo "Setting up git worktree for branch: $TARGET_BRANCH"
  if [[ -d "$OAG_REPO_DIR" ]]; then
    git worktree remove --force "$OAG_REPO_DIR" 2>/dev/null || true
  fi

  git worktree add "$OAG_REPO_DIR" "$TARGET_BRANCH"
else
  echo "Using current directory (already on target branch)"
fi

# Step 2: Clone DarwinPrivateFrameworks repository
echo "Cloning DarwinPrivateFrameworks repository..."
if [[ -d "$AG_REPO_DIR" ]]; then
  rm -rf "$AG_REPO_DIR"
fi

gh repo clone OpenSwiftUIProject/DarwinPrivateFrameworks "$AG_REPO_DIR"

# Step 3: Create new branch based on target branch name
echo "Creating new branch: update-ag-$TARGET_BRANCH"
cd "$AG_REPO_DIR"
git checkout -b "update-ag-$TARGET_BRANCH"

# Step 4: Generate AG template
echo "Generating AG template..."
cd "$OPENATTRIBUTEGRAPH_ROOT"
./Scripts/gen_ag_template.sh

# Step 5: Update DarwinPrivateFrameworks with generated content
echo "Updating DarwinPrivateFrameworks content..."

# Update headers in Sources/Headers
if [[ -d ".ag_template/Headers" ]]; then
  echo "Updating headers..."
  rm -rf "$AG_REPO_DIR/AG/2024/Sources/Headers"/*
  cp -r .ag_template/Headers/* "$AG_REPO_DIR/AG/2024/Sources/Headers/"
fi

# Update Swift interface template
if [[ -f ".ag_template/template.swiftinterface" ]]; then
  echo "Updating Swift interface template..."
  cp .ag_template/template.swiftinterface "$AG_REPO_DIR/AG/2024/Sources/Modules/AttributeGraph.swiftmodule/template.swiftinterface"
fi

# Step 6: Commit changes in DarwinPrivateFrameworks
echo "Committing changes..."
cd "$AG_REPO_DIR"

git add .
if git diff --staged --quiet; then
  echo "No changes to commit"
else
  git commit -m "feat(ag): Update AttributeGraph from OpenAttributeGraph $TARGET_BRANCH

- Updated headers from OpenAttributeGraph sources
- Updated Swift interface template
- Generated from OpenAttributeGraph branch: $TARGET_BRANCH"
fi

# Step 7: Update xcframeworks
echo "Updating xcframeworks..."
swift package update-xcframeworks --allow-writing-to-package-directory

# Commit xcframework updates
git add .
if git diff --staged --quiet; then
  echo "No xcframework changes to commit"
else
  git commit -m "chore(generated): Update AG framework"
fi

# Step 8: Push branch and create PR
echo "Pushing branch and creating PR..."
git push origin "update-ag-$TARGET_BRANCH" $FORCE_PUSH

# Create PR
PR_TITLE="Update AttributeGraph from OpenAttributeGraph $TARGET_BRANCH"
PR_BODY="Automated update of AttributeGraph framework from OpenAttributeGraph.

**Changes:**
- Updated headers from OpenAttributeGraph sources
- Updated Swift interface template
- Updated xcframework binaries

**Source Branch:** $TARGET_BRANCH
**Generated by:** OpenAttributeGraph bump script"

gh pr create \
  --title "$PR_TITLE" \
  --body "$PR_BODY" \
  --head "update-ag-$TARGET_BRANCH" \
  --base main

echo "✅ PR created successfully!"
echo "Branch: update-ag-$TARGET_BRANCH"
