#!/usr/bin/env bash
set -euo pipefail

# safe-git-merge.sh
#
# Purpose:
#   Safely inspect and resolve a Git branch merge conflict workflow with
#   non-destructive checks, clear prompts, and optional validation steps.
#
# Default behavior:
#   - Does NOT merge, commit, or push automatically.
#   - Performs read-only validation and prints the next safe commands.
#
# Usage:
#   ./safe-git-merge.sh --target <target-branch> --source <source-branch>
#
# Examples:
#   ./safe-git-merge.sh --target main --source feature/login-fix
#   ./safe-git-merge.sh --target release/1.2 --source bugfix/null-check
#
# Optional environment variables:
#   RUN_TESTS_CMD   Command to validate the repo after resolving conflicts.
#                   Example: RUN_TESTS_CMD="npm test" or "make test"
#   RUN_BUILD_CMD   Optional build/compile command.
#   SKIP_FETCH=1    Skip fetching from origin.
#
# Notes:
#   - This script assumes you will resolve conflicts manually.
#   - It avoids destructive actions such as reset, clean, force-push, or rebase.
#   - If your workflow requires different commands, edit the placeholders below.

usage() {
  cat <<'EOF'
Usage:
  safe-git-merge.sh --target <target-branch> --source <source-branch> [--validate-only]

Options:
  --target         Branch that will receive the merge.
  --source         Branch to merge into the target branch.
  --validate-only  Skip merge guidance and only run preflight/read-only checks.
  --help          Show this help message.
EOF
}

TARGET_BRANCH=""
SOURCE_BRANCH=""
VALIDATE_ONLY=0

while [[ $# -gt 0 ]]; do
  case "$1" in
    --target)
      TARGET_BRANCH="${2:-}"
      shift 2
      ;;
    --source)
      SOURCE_BRANCH="${2:-}"
      shift 2
      ;;
    --validate-only)
      VALIDATE_ONLY=1
      shift
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo "Unknown argument: $1" >&2
      usage
      exit 1
      ;;
  esac
done

require_git_repo() {
  if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "Error: This script must be run inside a Git repository." >&2
    exit 1
  fi
}

check_branch_exists() {
  local branch="$1"
  if ! git show-ref --verify --quiet "refs/heads/${branch}" && \
     ! git show-ref --verify --quiet "refs/remotes/origin/${branch}"; then
    echo "Warning: Branch '${branch}' was not found locally or on origin." >&2
    echo "         Verify the branch name before continuing." >&2
  fi
}

show_preflight() {
  echo "== Preflight checks =="
  echo
  echo "Current branch: $(git branch --show-current 2>/dev/null || echo 'unknown')"
  echo
  echo "Working tree status:"
  git status --short || true
  echo
  echo "If the working tree is dirty, stop and commit/stash your work before merging."
  echo

  if [[ "${SKIP_FETCH:-0}" != "1" ]]; then
    echo "Fetching latest remote references..."
    git fetch origin
  else
    echo "Skipping fetch because SKIP_FETCH=1 is set."
  fi

  if [[ -n "$TARGET_BRANCH" ]]; then
    echo
    echo "Checking out target branch: $TARGET_BRANCH"
    git checkout "$TARGET_BRANCH"

    echo
    echo "Updating local target branch with fast-forward only..."
    git pull --ff-only origin "$TARGET_BRANCH"
  fi
}

show_merge_guidance() {
  echo
  echo "== Merge guidance =="
  echo
  echo "Review these steps manually in your shell:"
  echo
  echo "  git merge ${SOURCE_BRANCH:-<source-branch>}"
  echo "  git status"
  echo "  git diff --merge"
  echo
  echo "Resolve each conflicted file carefully, then run:"
  echo
  echo "  git diff --check"
  echo "  git grep -n '<<<<<<<\\|=======\\|>>>>>>>'"
  echo "  git add <resolved-files>"
  echo "  git diff --cached"
  echo
  if [[ -n "${RUN_BUILD_CMD:-}" ]]; then
    echo "Optional build/compile check:"
    echo "  ${RUN_BUILD_CMD}"
    echo
  fi
  if [[ -n "${RUN_TESTS_CMD:-}" ]]; then
    echo "Optional test command:"
    echo "  ${RUN_TESTS_CMD}"
    echo
  fi
  echo "Finish with a merge commit if your workflow requires one:"
  echo "  git commit"
  echo
  echo "Then confirm the history:"
  echo "  git log --oneline --graph -n 5"
}

main() {
  require_git_repo

  if [[ -z "$TARGET_BRANCH" ]]; then
    echo "Error: --target is required." >&2
    usage
    exit 1
  fi

  if [[ -z "$SOURCE_BRANCH" && "$VALIDATE_ONLY" -eq 0 ]]; then
    echo "Error: --source is required unless --validate-only is used." >&2
    usage
    exit 1
  fi

  check_branch_exists "$TARGET_BRANCH"
  if [[ -n "$SOURCE_BRANCH" ]]; then
    check_branch_exists "$SOURCE_BRANCH"
  fi

  show_preflight

  if [[ "$VALIDATE_ONLY" -eq 1 ]]; then
    echo
    echo "Validate-only mode complete. No merge was performed."
    exit 0
  fi

  show_merge_guidance
}

main "$@"