#!/bin/bash
# Merge a worktree branch back to main with conflict-aware detection
# Usage: merge-worktree.sh <product-slug> <task-id>
#
# Exit codes:
#   0 = MERGE_SUCCESS
#   1 = MERGE_CONFLICT (git conflict)
#   2 = ERROR
#   3 = DIVERGENCE_CONFLICT (same files modified by concurrent task)
#   4 = DIVERGENCE_SAFE (different files, auto-merged)

set -e

SLUG=$1
TASK_ID=$2

if [ -z "$SLUG" ] || [ -z "$TASK_ID" ]; then
  echo "Usage: merge-worktree.sh <product-slug> <task-id>" >&2
  exit 2
fi

PRODUCT_DIR="/home/aria/products/$SLUG"
MAIN_DIR="$PRODUCT_DIR/apps/main"
WORKTREE_DIR="$PRODUCT_DIR/worktrees/$TASK_ID"
STATE_FILE="$PRODUCT_DIR/.worktree-state.json"
BRANCH="task/$TASK_ID"

cd "$MAIN_DIR"
git fetch origin >/dev/null 2>&1 || true

# Pull latest main first
git pull origin main >/dev/null 2>&1 || true

# Get current state
CURRENT_HEAD=$(git rev-parse HEAD)
BASE_COMMIT=$(jq -r ".active[\"$TASK_ID\"].base_commit // empty" "$STATE_FILE" 2>/dev/null)
REQUESTER=$(jq -r ".active[\"$TASK_ID\"].requester // \"unknown\"" "$STATE_FILE" 2>/dev/null)
REQUESTER_ID=$(jq -r ".active[\"$TASK_ID\"].requester_id // empty" "$STATE_FILE" 2>/dev/null)
DESCRIPTION=$(jq -r ".active[\"$TASK_ID\"].description // \"No description\"" "$STATE_FILE" 2>/dev/null)

# Check for divergence (someone else merged while we were working)
DIVERGED=false
DIVERGENCE_SAFE=true
OVERLAP_FILES=""
MAIN_CHANGES=""
OUR_CHANGES=""

if [ -n "$BASE_COMMIT" ] && [ "$CURRENT_HEAD" != "$BASE_COMMIT" ]; then
  DIVERGED=true
  
  # What changed in main since we branched?
  MAIN_CHANGES=$(git diff --name-only "$BASE_COMMIT" "$CURRENT_HEAD" 2>/dev/null | sort)
  
  # What are we trying to merge?
  OUR_CHANGES=$(git diff --name-only "$BASE_COMMIT" "$BRANCH" 2>/dev/null | sort)
  
  # Find overlap
  if [ -n "$MAIN_CHANGES" ] && [ -n "$OUR_CHANGES" ]; then
    OVERLAP_FILES=$(comm -12 <(echo "$MAIN_CHANGES") <(echo "$OUR_CHANGES") | tr '\n' ' ')
    if [ -n "$OVERLAP_FILES" ]; then
      DIVERGENCE_SAFE=false
    fi
  fi
fi

# If divergence with conflict risk, output details and exit
if [ "$DIVERGED" = true ] && [ "$DIVERGENCE_SAFE" = false ]; then
  echo "STATUS:DIVERGENCE_CONFLICT"
  echo "BASE_COMMIT:$BASE_COMMIT"
  echo "CURRENT_HEAD:$CURRENT_HEAD"
  echo "OVERLAP_FILES:$OVERLAP_FILES"
  
  # Get info about what merged since our base
  echo "RECENT_CHANGES:"
  git log --oneline "$BASE_COMMIT".."$CURRENT_HEAD" 2>/dev/null | head -5
  
  # Get recent merge info from state
  echo "RECENT_MERGES:"
  jq -r '.recent_merges[-3:][] | "\(.task_id)|\(.requester)|\(.merged_at)|\(.files | join(","))"' "$STATE_FILE" 2>/dev/null || true
  
  exit 3
fi

# If diverged but safe (different files), note it but proceed
if [ "$DIVERGED" = true ] && [ "$DIVERGENCE_SAFE" = true ]; then
  echo "STATUS:DIVERGENCE_SAFE"
  echo "NOTE:Different files modified, safe to merge"
fi

# Revert next.config.ts in worktree branch before merging (restore production security headers)
NEXT_CONFIG_WORKTREE="$WORKTREE_DIR/next.config.ts"
if [ -f "$NEXT_CONFIG_WORKTREE" ]; then
  cd "$WORKTREE_DIR"
  # Restore next.config.ts to the main branch version
  git show origin/main:next.config.ts > next.config.ts 2>/dev/null || \
    git show main:next.config.ts > next.config.ts 2>/dev/null || true
  if ! git diff --quiet next.config.ts 2>/dev/null; then
    git add next.config.ts
    git commit -m "chore(worktree): revert frame-ancestors to DENY before merge" --no-verify 2>/dev/null || true
  fi
  cd "$MAIN_DIR"
fi

# Attempt merge
if git merge "$BRANCH" --no-edit 2>/dev/null; then
  echo "STATUS:MERGE_SUCCESS"
  MERGE_COMMIT=$(git rev-parse HEAD)
  git push origin main 2>/dev/null || echo "WARN:Push failed, committed locally"
  
  # Get files we changed
  MERGED_FILES=$(git diff --name-only "$BASE_COMMIT" "$MERGE_COMMIT" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
  
  # Cleanup worktree
  git worktree remove "$WORKTREE_DIR" --force 2>/dev/null || rm -rf "$WORKTREE_DIR"
  git branch -D "$BRANCH" 2>/dev/null || true
  git push origin --delete "$BRANCH" 2>/dev/null || true
  
  # Update state: remove from active, add to recent_merges
  if [ -f "$STATE_FILE" ]; then
    jq --arg id "$TASK_ID" \
       --arg req "$REQUESTER" \
       --arg req_id "$REQUESTER_ID" \
       --arg merged "$(date -Iseconds)" \
       --arg commit "$MERGE_COMMIT" \
       --arg files "$MERGED_FILES" \
       --arg desc "$DESCRIPTION" \
       'del(.active[$id]) | .recent_merges = (.recent_merges + [{task_id: $id, requester: $req, requester_id: $req_id, description: $desc, merged_at: $merged, commit: $commit, files: ($files | split(","))}] | .[-10:])' \
       "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
  fi
  
  exit 0
else
  echo "STATUS:MERGE_CONFLICT"
  git merge --abort 2>/dev/null || true
  
  # List conflicting files
  echo "CONFLICTS:"
  git merge --no-commit "$BRANCH" 2>/dev/null || true
  git diff --name-only --diff-filter=U 2>/dev/null || true
  git merge --abort 2>/dev/null || true
  
  exit 1
fi
