#!/bin/sh
#
# git-issue-export-gitea - Export issues to Gitea/Forgejo
#
# Usage: git issue export gitea:<owner>/<repo> [options]
#        git issue export forgejo:<owner>/<repo> [options]
#

set -e

usage() {
	cat <<EOF
usage: git issue export gitea:<owner>/<repo> [options]
       git issue export forgejo:<owner>/<repo> [options]

Options:
   --url <url>       Instance URL (default: https://gitea.com for gitea, https://codeberg.org for forgejo)
   --token <token>   API token (or use GITEA_TOKEN/FORGEJO_TOKEN env var)
   --dry-run         Show what would be exported without exporting
   -h, --help        Show this help

Authentication:
   Requires an API token with 'write:issue' scope.
   Provide via --token flag, GITEA_TOKEN/FORGEJO_TOKEN env var, or config file:
   ~/.config/git-native-issue/gitea-token
   ~/.config/git-native-issue/forgejo-token
EOF
	exit 1
}

provider=""
dry_run=0
api_url=""
api_token=""
platform=""

while test $# -gt 0
do
	case "$1" in
		--url)
			test $# -ge 2 || { echo "error: --url requires a value" >&2; exit 1; }
			api_url="$2"
			shift 2
			;;
		--token)
			test $# -ge 2 || { echo "error: --token requires a value" >&2; exit 1; }
			api_token="$2"
			shift 2
			;;
		--dry-run)
			dry_run=1
			shift
			;;
		-h|--help)
			usage
			;;
		--)
			shift
			break
			;;
		-*)
			echo "error: unknown option '$1'" >&2
			usage
			;;
		*)
			if test -z "$provider"
			then
				provider="$1"
			fi
			shift
			;;
	esac
done

if test -z "$provider"
then
	echo "error: provider is required (e.g., gitea:owner/repo or forgejo:owner/repo)" >&2
	usage
fi

# Parse provider string
case "$provider" in
	gitea:*/*)
		platform="gitea"
		repo_path="${provider#gitea:}"
		owner="${repo_path%/*}"
		repo="${repo_path#*/}"
		;;
	forgejo:*/*)
		platform="forgejo"
		repo_path="${provider#forgejo:}"
		owner="${repo_path%/*}"
		repo="${repo_path#*/}"
		;;
	*)
		echo "error: invalid provider string '$provider'" >&2
		echo "       expected format: gitea:<owner>/<repo> or forgejo:<owner>/<repo>" >&2
		exit 1
		;;
esac

# Verify we are inside a git repository
git rev-parse --git-dir >/dev/null 2>&1 || {
	echo "fatal: not a git repository" >&2
	exit 128
}

# Source shared library for user cache functions
. "$(dirname "$0")/git-issue-lib"

# Check prerequisites
command -v jq >/dev/null 2>&1 || {
	echo "error: 'jq' is required but not found" >&2
	echo "       install: https://stedolan.github.io/jq/" >&2
	exit 1
}

command -v curl >/dev/null 2>&1 || {
	echo "error: 'curl' is required but not found" >&2
	exit 1
}

# Set default API URL based on platform
if test -z "$api_url"
then
	case "$platform" in
		gitea)
			api_url="https://gitea.com"
			;;
		forgejo)
			api_url="https://codeberg.org"
			;;
	esac
fi

# Remove trailing slash from URL
api_url="${api_url%/}"

# Get API token from various sources
if test -z "$api_token"
then
	# Try environment variables
	if test -n "$GITEA_TOKEN"
	then
		api_token="$GITEA_TOKEN"
	elif test -n "$FORGEJO_TOKEN"
	then
		api_token="$FORGEJO_TOKEN"
	# Try config files
	elif test -r "$HOME/.config/git-native-issue/gitea-token"
	then
		api_token="$(cat "$HOME/.config/git-native-issue/gitea-token")"
	elif test -r "$HOME/.config/git-native-issue/forgejo-token"
	then
		api_token="$(cat "$HOME/.config/git-native-issue/forgejo-token")"
	else
		echo "error: API token required but not found" >&2
		echo "       provide via --token, GITEA_TOKEN/FORGEJO_TOKEN env var, or config file" >&2
		echo "       config: ~/.config/git-native-issue/gitea-token" >&2
		exit 1
	fi
fi

# Verify API token (skip in dry-run)
if test "$dry_run" -eq 0
then
	version_response="$(curl -s -H "Authorization: token $api_token" "$api_url/api/v1/version" 2>&1)"

	if ! printf '%s' "$version_response" | jq empty 2>/dev/null
	then
		echo "error: failed to connect to $api_url" >&2
		echo "       check URL and token" >&2
		echo "       response: $version_response" >&2
		exit 1
	fi
fi

# Auto-seed user cache from authenticated user
if test "$dry_run" -eq 0 && test -n "$api_token"
then
	_authed_user="$(curl -s -H "Authorization: token $api_token" "$api_url/api/v1/user" 2>/dev/null || echo '{}')"
	_authed_email="$(printf '%s' "$_authed_user" | jq -r '.email // empty')"
	_authed_login="$(printf '%s' "$_authed_user" | jq -r '.login // empty')"
	_authed_id="$(printf '%s' "$_authed_user" | jq -r '.id // empty')"

	if test -n "$_authed_email" && test -n "$_authed_login" && test -n "$_authed_id"
	then
		cache_platform_user "$_authed_email" "$_authed_login" "$_authed_id" "$platform"
	fi
fi

# Resolve an email to a Gitea/Forgejo username for assignee export
# Uses three-tier lookup: cache -> Gitea user search API -> noreply pattern
resolve_gitea_assignee() {
	_rta_email="$1"

	# Tier 1: Persistent cache (populated during import)
	_rta_login="$(lookup_cached_login "$_rta_email" "$platform")"
	if test -n "$_rta_login"
	then
		# Verify the user still exists on the instance
		_rta_verify="$(curl -s -H "Authorization: token $api_token" \
			"$api_url/api/v1/users/$_rta_login" 2>/dev/null || echo '{}')"
		_rta_verify_id="$(printf '%s' "$_rta_verify" | jq -r '.id // empty')"
		if test -n "$_rta_verify_id"
		then
			printf '%s' "$_rta_login"
			return 0
		fi
	fi

	# Tier 2: Gitea user search API (works for public emails)
	_rta_search="$(curl -s -H "Authorization: token $api_token" \
		"$api_url/api/v1/users/search?q=$(printf '%s' "$_rta_email" | jq -sRr @uri)" 2>/dev/null || echo '{"data":[]}')"
	_rta_found_login="$(printf '%s' "$_rta_search" | jq -r '.data[0].login // empty')"
	_rta_found_id="$(printf '%s' "$_rta_search" | jq -r '.data[0].id // empty')"
	_rta_found_email="$(printf '%s' "$_rta_search" | jq -r '.data[0].email // empty')"

	if test -n "$_rta_found_login"
	then
		# Verify the search result email matches
		if test "$_rta_found_email" = "$_rta_email"
		then
			cache_platform_user "$_rta_email" "$_rta_found_login" "$_rta_found_id" "$platform"
			printf '%s' "$_rta_found_login"
			return 0
		fi
	fi

	# Tier 3: Extract username from noreply email pattern
	case "$_rta_email" in
		*@users.noreply.${platform}.com)
			_rta_noreply_login="${_rta_email%@users.noreply.${platform}.com}"
			# Verify user exists on the instance
			_rta_noreply_verify="$(curl -s -H "Authorization: token $api_token" \
				"$api_url/api/v1/users/$_rta_noreply_login" 2>/dev/null || echo '{}')"
			_rta_noreply_id="$(printf '%s' "$_rta_noreply_verify" | jq -r '.id // empty')"
			if test -n "$_rta_noreply_id"
			then
				cache_platform_user "$_rta_email" "$_rta_noreply_login" "$_rta_noreply_id" "$platform"
				printf '%s' "$_rta_noreply_login"
				return 0
			fi
			;;
	esac

	# All lookups failed
	return 0
}

# Get the empty tree SHA
empty_tree="$(git hash-object -t tree /dev/null)"

exported=0
skipped=0
synced=0

target_prefix="$platform:$owner/$repo#"

tmpfile="$(mktemp)"
refs_file="$(mktemp)"
trap 'rm -f "$tmpfile" "$refs_file"' EXIT

# Fetch and cache all existing labels from target repository (skip in dry-run)
if test "$dry_run" -eq 0
then
	all_labels_json="$(curl -s -H "Authorization: token $api_token" \
		"$api_url/api/v1/repos/$owner/$repo/labels?limit=100" 2>&1)"

	# Validate labels response
	if ! printf '%s' "$all_labels_json" | jq empty 2>/dev/null
	then
		echo "warning: failed to fetch labels from $platform, label creation may fail" >&2
		all_labels_json="[]"
	fi
else
	all_labels_json="[]"
fi

# Helper function: get or create label ID by name
# Usage: label_id=$(get_or_create_label_id "enhancement")
get_or_create_label_id() {
	label_name="$1"

	# Check if label exists in cache
	label_id="$(printf '%s' "$all_labels_json" | jq -r --arg name "$label_name" \
		'.[] | select(.name == $name) | .id')"

	if test -n "$label_id"
	then
		printf '%s' "$label_id"
		return 0
	fi

	# Label doesn't exist - create it
	# Use a default color based on label name
	case "$label_name" in
		bug|fix) color="#d73a4a" ;;
		enhancement|feature) color="#a2eeef" ;;
		documentation|docs) color="#0075ca" ;;
		question) color="#d876e3" ;;
		duplicate) color="#cfd3d7" ;;
		help*) color="#008672" ;;
		*) color="#84b6eb" ;;  # default blue
	esac

	create_label_payload="$(jq -n \
		--arg name "$label_name" \
		--arg color "$color" \
		--arg description "Auto-created by git-issue export" \
		'{name: $name, color: $color, description: $description}')"

	create_label_response="$(curl -s -X POST \
		-H "Authorization: token $api_token" \
		-H "Content-Type: application/json" \
		-d "$create_label_payload" \
		"$api_url/api/v1/repos/$owner/$repo/labels" 2>&1)"

	# Extract new label ID
	new_label_id="$(printf '%s' "$create_label_response" | jq -r '.id // empty')"

	if test -z "$new_label_id"
	then
		echo "warning: failed to create label '$label_name'" >&2
		return 1
	fi

	# Add to cache for future lookups
	all_labels_json="$(printf '%s' "$all_labels_json" | jq --argjson new "$create_label_response" '. + [$new]')"

	printf '%s' "$new_label_id"
	return 0
}

# Write refs to file to avoid subshell pipeline
git for-each-ref --format='%(refname)' refs/issues/ > "$refs_file"

while IFS= read -r ref
do
	uuid="${ref#refs/issues/}"
	short_id="$(printf '%s' "$uuid" | cut -c1-7)"

	# Get root commit
	root="$(git rev-list --max-parents=0 "$ref")"
	title="$(git log -1 --format='%s' "$root")"

	# Extract body, stripping trailer block
	raw_body="$(git log -1 --format='%b' "$root")"
	body=""
	if test -n "$raw_body"
	then
		trailer_block="$(printf '%s\n' "$raw_body" | git interpret-trailers --parse 2>/dev/null)" || trailer_block=""
		if test -n "$trailer_block"
		then
			n_trailers="$(printf '%s\n' "$trailer_block" | wc -l | tr -d ' ')"
			n_body="$(printf '%s\n' "$raw_body" | wc -l | tr -d ' ')"
			# Subtract trailers + blank separator line
			n_keep=$((n_body - n_trailers - 1))
			if test "$n_keep" -gt 0
			then
				body="$(printf '%s\n' "$raw_body" | head -n "$n_keep")"
			fi
		else
			body="$raw_body"
		fi
	fi

	# Get current state
	state="$(git log --format='%(trailers:key=State,valueonly)' "$ref" | sed '/^$/d' | head -1)"
	state="$(printf '%s' "$state" | sed 's/^[[:space:]]*//')"

	# Get labels
	labels="$(git log --format='%(trailers:key=Labels,valueonly)' "$ref" | sed '/^$/d' | head -1)"
	labels="$(printf '%s' "$labels" | sed 's/^[[:space:]]*//')"

	# Get assignee (canonical email)
	# Use full trailer format to distinguish "no trailer" from "empty value"
	_assignee_line="$(git log --format='%(trailers:key=Assignee)' "$ref" | sed '/^$/d' | head -1)"
	has_assignee=0
	assignee_email=""
	if test -n "$_assignee_line"
	then
		has_assignee=1
		assignee_email="$(printf '%s' "$_assignee_line" | sed 's/^Assignee:[[:space:]]*//')"
	fi

	# Check for Provider-ID in commit chain
	existing_pid=""
	existing_pid="$(git log --format='%(trailers:key=Provider-ID,valueonly)' "$ref" | \
		sed '/^$/d' | sed 's/^[[:space:]]*//' | head -1)"

	if test -n "$existing_pid"
	then
		# Check if this Provider-ID is for the target repo
		case "$existing_pid" in
			"$target_prefix"*)
				# Already exported to this repo — sync comments and state
				issue_number="${existing_pid#$target_prefix}"

				if test "$dry_run" -eq 1
				then
					printf '[dry-run] Would sync %s (already exported as #%s)\n' "$short_id" "$issue_number"
					synced=$((synced + 1))
					continue
				fi

				# Get all commit SHAs that have already been exported
				exported_commits="$(git log --format='%(trailers:key=Exported-Commit,valueonly)' "$ref" | sed '/^$/d' | sed 's/^[[:space:]]*//')"

				# Export new comments
				issue_head="$(git rev-parse "$ref")"
				commits="$(git rev-list --reverse "$root..$ref")"
				new_comments_exported=0
				parent="$issue_head"

				for cmt in $commits
				do
					# Skip if already exported
					if echo "$exported_commits" | grep -qF "$cmt" 2>/dev/null
					then
						continue
					fi

					# Skip if has Provider-Comment-ID (imported comment)
					cmt_provider_comment_id="$(git log -1 --format='%(trailers:key=Provider-Comment-ID,valueonly)' "$cmt" | sed '/^$/d' | sed 's/^[[:space:]]*//')"
					if test -n "$cmt_provider_comment_id"
					then
						continue
					fi

					# Skip state changes
					cmt_state_trailer="$(git log -1 --format='%(trailers:key=State,valueonly)' "$cmt" | sed '/^$/d')"
					if test -n "$cmt_state_trailer"
					then
						continue
					fi

					# Skip Provider-ID record commits
					cmt_provider_id="$(git log -1 --format='%(trailers:key=Provider-ID,valueonly)' "$cmt" | sed '/^$/d')"
					if test -n "$cmt_provider_id" && test "$cmt_provider_id" = "$existing_pid"
					then
						continue
					fi

					# Export comment
					cmt_subject="$(git log -1 --format='%s' "$cmt")"
					cmt_body_full="$(git log -1 --format='%b' "$cmt")"

					# Strip trailers from body
					cmt_body=""
					if test -n "$cmt_body_full"
					then
						cmt_trailers="$(printf '%s\n' "$cmt_body_full" | git interpret-trailers --parse 2>/dev/null)" || cmt_trailers=""
						if test -n "$cmt_trailers"
						then
							n_trailers="$(printf '%s\n' "$cmt_trailers" | wc -l | tr -d ' ')"
							n_body="$(printf '%s\n' "$cmt_body_full" | wc -l | tr -d ' ')"
							n_keep=$((n_body - n_trailers - 1))
							if test "$n_keep" -gt 0
							then
								cmt_body="$(printf '%s\n' "$cmt_body_full" | head -n "$n_keep")"
							fi
						else
							cmt_body="$cmt_body_full"
						fi
					fi

					comment_text="$cmt_subject"
					if test -n "$cmt_body"
					then
						comment_text="$comment_text

$cmt_body"
					fi

					# Post comment to Gitea/Forgejo
					comment_response="$(curl -s -f -X POST \
						-H "Authorization: token $api_token" \
						-H "Content-Type: application/json" \
						-d "$(jq -n --arg body "$comment_text" '{body: $body}')" \
						"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number/comments" 2>/dev/null)" || continue

					# Extract comment ID
					comment_id="$(printf '%s' "$comment_response" | jq -r '.id' 2>/dev/null)"

					if test -n "$comment_id" && test "$comment_id" != "null"
					then
						# Record Provider-Comment-ID
						comment_provider_id="$platform:$owner/$repo#comment-$comment_id"
						printf 'Record export of comment to %s #%s\n' "$platform" "$issue_number" > "$tmpfile"
						git interpret-trailers --in-place \
							--trailer "Provider-Comment-ID: $comment_provider_id" \
							--trailer "Exported-Commit: $cmt" \
							"$tmpfile"

						new_commit="$(git commit-tree -p "$parent" -- "$empty_tree" < "$tmpfile")"
						parent="$new_commit"
						new_comments_exported=$((new_comments_exported + 1))
					fi
				done

				# Update ref if we exported comments
				if test "$new_comments_exported" -gt 0
				then
					git update-ref "$ref" "$parent" "$issue_head"
				fi

				# Sync state
				case "$state" in
					closed)
						curl -s -f -X PATCH \
							-H "Authorization: token $api_token" \
							-H "Content-Type: application/json" \
							-d '{"state": "closed"}' \
							"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number" >/dev/null 2>&1 || true
						;;
					open)
						curl -s -f -X PATCH \
							-H "Authorization: token $api_token" \
							-H "Content-Type: application/json" \
							-d '{"state": "open"}' \
							"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number" >/dev/null 2>&1 || true
						;;
				esac

				# Sync assignee (only if local issue has an opinion)
				if test "$has_assignee" -eq 1
				then
					if test -n "$assignee_email"
					then
						_sync_login="$(resolve_gitea_assignee "$assignee_email")"
						if test -n "$_sync_login"
						then
							curl -s -f -X PATCH \
								-H "Authorization: token $api_token" \
								-H "Content-Type: application/json" \
								-d "$(jq -n --arg a "$_sync_login" '{assignee: $a}')" \
								"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number" >/dev/null 2>&1 || {
								printf 'Warning: failed to sync assignee %s to #%s\n' "$_sync_login" "$issue_number" >&2
							}
						else
							printf 'Warning: could not resolve %s to %s user for %s\n' "$assignee_email" "$platform" "$short_id" >&2
						fi
					else
						# Explicitly unassigned in local issue
						curl -s -f -X PATCH \
							-H "Authorization: token $api_token" \
							-H "Content-Type: application/json" \
							-d '{"assignee": ""}' \
							"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number" >/dev/null 2>&1 || true
					fi
				fi

				synced=$((synced + 1))
				if test "$new_comments_exported" -gt 0
				then
					printf 'Synced %s with #%s (%d new comment(s) exported)\n' "$short_id" "$issue_number" "$new_comments_exported"
				else
					printf 'Synced %s with #%s\n' "$short_id" "$issue_number"
				fi
				continue
				;;
			*)
				# Foreign Provider-ID (from different source)
				skipped=$((skipped + 1))
				printf 'Skipped %s (imported from %s)\n' "$short_id" "$existing_pid"
				continue
				;;
		esac
	fi

	# No Provider-ID — export as new issue
	if test "$dry_run" -eq 1
	then
		printf '[dry-run] Would export %s: %s\n' "$short_id" "$title"
		exported=$((exported + 1))
		continue
	fi

	# Build labels array - resolve label names to IDs
	labels_array="[]"
	if test -n "$labels"
	then
		# Split comma-separated labels and get/create each label ID
		label_ids=""
		IFS=','
		for label_name in $labels
		do
			# Trim whitespace
			label_name="$(printf '%s' "$label_name" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"

			# Get or create label ID
			label_id="$(get_or_create_label_id "$label_name")"

			if test -n "$label_id"
			then
				if test -z "$label_ids"
				then
					label_ids="$label_id"
				else
					label_ids="$label_ids,$label_id"
				fi
			fi
		done
		unset IFS

		# Convert comma-separated IDs to JSON array of integers
		if test -n "$label_ids"
		then
			labels_array="$(printf '%s' "$label_ids" | awk 'BEGIN{printf "["} {split($0,a,","); for(i=1;i<=length(a);i++){if(i>1)printf ","; printf "%s",a[i]}} END{printf "]"}')"
		fi
	fi

	# Resolve assignee email to platform username
	assignee_login=""
	if test "$has_assignee" -eq 1 && test -n "$assignee_email"
	then
		assignee_login="$(resolve_gitea_assignee "$assignee_email")"
		if test -z "$assignee_login"
		then
			printf 'Warning: could not resolve %s to %s user for %s\n' "$assignee_email" "$platform" "$short_id" >&2
		fi
	fi

	# Create issue on Gitea/Forgejo
	if test -n "$assignee_login"
	then
		create_payload="$(jq -n \
			--arg title "$title" \
			--arg body "$body" \
			--argjson labels "$labels_array" \
			--arg assignee "$assignee_login" \
			'{title: $title, body: $body, labels: $labels, assignee: $assignee}')"
	else
		create_payload="$(jq -n \
			--arg title "$title" \
			--arg body "$body" \
			--argjson labels "$labels_array" \
			'{title: $title, body: $body, labels: $labels}')"
	fi

	create_response="$(curl -s -X POST \
		-H "Authorization: token $api_token" \
		-H "Content-Type: application/json" \
		-d "$create_payload" \
		"$api_url/api/v1/repos/$owner/$repo/issues" 2>&1)"

	# Validate JSON response
	if ! printf '%s' "$create_response" | jq empty 2>/dev/null
	then
		echo "error: failed to create issue on $platform (invalid response)" >&2
		echo "       response: $create_response" >&2
		continue
	fi

	# Check for API errors
	if printf '%s' "$create_response" | jq -e '.message // .error' >/dev/null 2>&1
	then
		error_msg="$(printf '%s' "$create_response" | jq -r '.message // .error // "unknown error"')"
		echo "error: API error creating issue: $error_msg" >&2
		echo "       response: $create_response" >&2
		continue
	fi

	issue_number="$(printf '%s' "$create_response" | jq -r '.number')"
	provider_id="$platform:$owner/$repo#$issue_number"

	# Export comments (skip root, skip metadata commits)
	issue_head="$(git rev-parse "$ref")"
	commits="$(git rev-list --reverse "$root..$ref")"
	parent="$issue_head"
	comments_exported=0

	for cmt in $commits
	do
		# Skip commits with trailers (metadata changes)
		cmt_trailers="$(git log -1 --format='%(trailers)' "$cmt" | sed '/^$/d')"
		if test -n "$cmt_trailers"
		then
			continue
		fi

		cmt_subject="$(git log -1 --format='%s' "$cmt")"
		cmt_full="$(git log -1 --format='%b' "$cmt" | sed '/^$/d')"

		comment_text="$cmt_subject"
		if test -n "$cmt_full"
		then
			comment_text="$comment_text

$cmt_full"
		fi

		# Post comment to Gitea/Forgejo
		comment_response="$(curl -s -f -X POST \
			-H "Authorization: token $api_token" \
			-H "Content-Type: application/json" \
			-d "$(jq -n --arg body "$comment_text" '{body: $body}')" \
			"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number/comments" 2>/dev/null)" || continue

		comment_id="$(printf '%s' "$comment_response" | jq -r '.id' 2>/dev/null)"

		if test -n "$comment_id" && test "$comment_id" != "null"
		then
			# Record Provider-Comment-ID and Exported-Commit
			comment_provider_id="$platform:$owner/$repo#comment-$comment_id"
			printf 'Record export of comment to %s #%s\n' "$platform" "$issue_number" > "$tmpfile"
			git interpret-trailers --in-place \
				--trailer "Provider-Comment-ID: $comment_provider_id" \
				--trailer "Exported-Commit: $cmt" \
				"$tmpfile"

			new_commit="$(git commit-tree -p "$parent" -- "$empty_tree" < "$tmpfile")"
			parent="$new_commit"
			comments_exported=$((comments_exported + 1))
		fi
	done

	# Sync state if closed
	if test "$state" = "closed"
	then
		curl -s -f -X PATCH \
			-H "Authorization: token $api_token" \
			-H "Content-Type: application/json" \
			-d '{"state": "closed"}' \
			"$api_url/api/v1/repos/$owner/$repo/issues/$issue_number" >/dev/null 2>&1 || true
	fi

	# Record Provider-ID locally
	printf '%s\n' "Record export to $platform #$issue_number" > "$tmpfile"
	git interpret-trailers --in-place --trailer "Provider-ID: $provider_id" "$tmpfile"

	# Use parent from comment chain if comments were exported
	if test "$comments_exported" -gt 0
	then
		new_commit="$(git commit-tree -p "$parent" -- "$empty_tree" < "$tmpfile")"
	else
		new_commit="$(git commit-tree -p "$issue_head" -- "$empty_tree" < "$tmpfile")"
	fi
	git update-ref -- "$ref" "$new_commit" "$issue_head"

	exported=$((exported + 1))
	printf 'Exported %s as #%s: %s\n' "$short_id" "$issue_number" "$title"
done < "$refs_file"

printf 'Exported %d issues (%d skipped, %d synced)\n' "$exported" "$skipped" "$synced"
