#!/bin/bash

# shellcheck shell=bash

# Merge from primary
bridge_merge_from_primary() {
  # Parse args: --worktree <path> --branch <name>
  shift || true
  wt=""; br=""
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --worktree) wt="$2"; shift 2;;
      --branch) br="$2"; shift 2;;
      *) shift;;
    esac
  done
  if [[ -z "$wt" || -z "$br" ]]; then
    json_error "--worktree and --branch required"; return 1
  fi
  if ! git_require_repo_root >/dev/null 2>&1; then
    json_error "Not a git repository"; return 1
  fi
  pr="$(git_primary_branch || true)"
  if [[ -z "$pr" ]]; then
    json_object \
      "ok:b=false" \
      "operation:s=merge-from-primary" \
      "error_type:s=no_primary_detected" \
      "message:s=Could not detect primary branch"
    return 0
  fi
  LOGS=""
  append() { LOGS+="$1"$'\n'; }
  # Fetch in target worktree
  append "$ git -C $wt fetch origin --prune"
  append "$(git_fetch_prune "$wt")"
  # If primary worktree exists, update it fast-forward-only
  pr_path="$(git_branch_to_worktree_path "$pr" || true)"
  if [[ -n "$pr_path" ]]; then
    if ! git_is_worktree_clean "$pr_path"; then
      logs_json="$(json_array_from_lines "$LOGS")"
      json_object \
        "ok:b=false" \
        "operation:s=merge-from-primary" \
        "error_type:s=dirty_primary" \
        "message:s=Primary worktree is dirty" \
        "primary:s=$pr" \
        "target_branch:s=$br" \
        "target_path:s=$wt" \
        "logs:j=$logs_json"
      return 0
    fi
    append "$ git -C $pr_path pull --ff-only"
    set +e
    pull_out="$(git_pull_ff_only "$pr_path")"
    sts=$?
    set -e
    append "$pull_out"
    if [[ $sts -ne 0 ]]; then
      logs_json="$(json_array_from_lines "$LOGS")"
      json_object \
        "ok:b=false" \
        "operation:s=merge-from-primary" \
        "error_type:s=ff_only_failed" \
        "message:s=Primary cannot fast-forward" \
        "primary:s=$pr" \
        "target_branch:s=$br" \
        "target_path:s=$wt" \
        "logs:j=$logs_json"
      return 0
    fi
  fi
  # Choose ref to merge
  if git -C "$wt" rev-parse --verify "origin/$pr" >/dev/null 2>&1; then
    ref="origin/$pr"
  else
    ref="$pr"
  fi
  append "$ git -C $wt merge $ref"
  set +e
  out="$(git_merge_into "$wt" "$ref")"
  rc=$?
  set -e
  append "$out"
  summary="$(git_error_summary "$out")"
  if [[ -z "$summary" ]]; then
    summary="Merge conflict or error"
  fi
  logs_json="$(json_array_from_lines "$LOGS")"
  if [[ $rc -eq 0 ]]; then
    result="merged"
    if echo "$out" | grep -qi 'already up[- ]to[- ]date'; then result="up_to_date"; fi
    json_object \
      "ok:b=true" \
      "operation:s=merge-from-primary" \
      "primary:s=$pr" \
      "target_branch:s=$br" \
      "target_path:s=$wt" \
      "result:s=$result" \
      "logs:j=$logs_json"
  else
    json_object \
      "ok:b=false" \
      "operation:s=merge-from-primary" \
      "error_type:s=merge_conflict" \
      "message:s=$summary" \
      "primary:s=$pr" \
      "target_branch:s=$br" \
      "target_path:s=$wt" \
      "logs:j=$logs_json"
  fi
}
