#!/bin/bash

# shellcheck shell=bash

# Merge into primary
bridge_merge_into_primary() {
  shift || true
  wt=""; br=""; msg=""
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --worktree) wt="$2"; shift 2;;
      --branch) br="$2"; shift 2;;
      --message) msg="$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-into-primary" \
      "error_type:s=no_primary_detected" \
      "message:s=Could not detect primary branch"
    return 0
  fi
  LOGS=""; append() { LOGS+="$1"$'\n'; }
  pr_path="$(git_ensure_primary_worktree || true)"
  if [[ -z "$pr_path" ]]; then
    json_object \
      "ok:b=false" \
      "operation:s=merge-into-primary" \
      "error_type:s=ensure_primary_failed" \
      "message:s=Failed to ensure primary worktree"
    return 0
  fi
  if ! git_is_worktree_clean "$pr_path"; then
    json_object \
      "ok:b=false" \
      "operation:s=merge-into-primary" \
      "error_type:s=dirty_primary" \
      "message:s=Primary worktree is dirty" \
      "primary:s=$pr"
    return 0
  fi
  append "$ git -C $pr_path fetch origin --prune"
  append "$(git_fetch_prune "$pr_path")"
  append "$ git -C $pr_path pull --ff-only"
  set +e
  pull_out="$(git_pull_ff_only "$pr_path")"
  pull_rc=$?
  set -e
  append "$pull_out"
  if [[ $pull_rc -ne 0 ]]; then
    logs_json="$(json_array_from_lines "$LOGS")"
    json_object \
      "ok:b=false" \
      "operation:s=merge-into-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
  if [[ -n "$msg" ]]; then
    append "$ git -C $pr_path merge --no-ff -m '$msg' $br"
    set +e
    out="$(git -C "$pr_path" merge --no-ff -m "$msg" "$br" 2>&1)"
    rc=$?
    set -e
  else
    append "$ git -C $pr_path merge --no-ff $br"
    set +e
    out="$(git -C "$pr_path" merge --no-ff "$br" 2>&1)"
    rc=$?
    set -e
  fi
  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
    # Detect no-op merge (already up to date)
    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-into-primary" \
      "primary:s=$pr" \
      "target_branch:s=$br" \
      "primary_path:s=$pr_path" \
      "result:s=$result" \
      "logs:j=$logs_json"
  else
    json_object \
      "ok:b=false" \
      "operation:s=merge-into-primary" \
      "error_type:s=merge_conflict" \
      "message:s=$summary" \
      "primary:s=$pr" \
      "target_branch:s=$br" \
      "primary_path:s=$pr_path" \
      "logs:j=$logs_json"
  fi
}
