#!/bin/bash

## Copyright (C) 2026 - 2026 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## AI-Assisted

## Two phases: sign HEAD if unsigned (rewrites the commit via amend),
## then tag HEAD if no signed tag points at it.
##
## Args:
##   $1 - context label for operator-facing log lines. Pass
##        'main repo' for the parent repo, "${displaypath}" inside
##        'git submodule foreach'. Required.

set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit
shopt -s shift_verbose

repo_root="$(cd -- "$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")/.." && pwd)"

## variables.bsh's source cds away as a side effect. CWD must stay
## at the caller's working tree (= the submodule when foreach lands
## us there) so git operates on the right git db.
saved_cwd="${PWD}"
export dist_build_source_run=true
export dist_build_one_parsed=true
# shellcheck source=help-steps/pre
source "${repo_root}/help-steps/pre"
# shellcheck source=help-steps/variables
source "${repo_root}/help-steps/variables"
cd -- "${saved_cwd}"

# shellcheck source=help-steps/verify-ref
source "${repo_root}/help-steps/verify-ref"

context_label="${1:?context label arg required}"

## Phase 1: sign HEAD if unsigned.
if verify_ref HEAD commit "${context_label} HEAD"; then
   printf '%s\n' "${BASH_SOURCE[0]}: ${context_label} HEAD already signed"
else
   "${git_signing_command_wrapper[@]}" commit --amend --no-edit -S
   printf '%s\n' "${BASH_SOURCE[0]}: ${context_label} HEAD re-signed"
fi

## Phase 2: tag HEAD. git_sanity_test (mode_working_tree) requires
## exactly zero or one signed annotated tag at HEAD; mirror that
## classification so we don't leave the repo in a state the next
## sanity check rejects.
git_tags_at_head_output="$(git for-each-ref --points-at=HEAD --format='%(refname)' refs/tags)"
if [ -n "${git_tags_at_head_output:-}" ]; then
   readarray -t tags_at_head <<< "${git_tags_at_head_output}"
else
   tags_at_head=()
fi

case "${#tags_at_head[@]}" in
   0)
      true "INFO: ${context_label} has no tag at HEAD; will create a signed tag below"
      ## Signed tag creation occurs later.
      ;;
   1)
      if verify_ref "${tags_at_head[0]}" tag "${context_label} tag"; then
         printf '%s\n' "${BASH_SOURCE[0]}: ${context_label} already has signed tag: ${tags_at_head[0]}"
         exit 0
      fi
      printf '%s\n' "${BASH_SOURCE[0]}: ${context_label} has unsigned tag '${tags_at_head[0]}' at HEAD; remove it ('git tag -d ...') before re-running" >&2
      exit 1
      ;;
   *)
      printf '%s\n' "${BASH_SOURCE[0]}: ${context_label} has multiple tags at HEAD: ${tags_at_head[*]}; remove extras ('git tag -d ...') before re-running" >&2
      exit 1
      ;;
esac

commit_full_sha="$(git rev-parse HEAD)"
if nearest_git_tag="$(git describe --abbrev=0 2>/dev/null)"; then
   signed_tag="${nearest_git_tag}_${commit_full_sha}"
else
   signed_tag="tag_${commit_full_sha}"
fi
printf '%s\n' "${BASH_SOURCE[0]}: creating signed annotated tag for ${context_label}: ${signed_tag} (commit ${commit_full_sha})"
## Don't pass `-a` here, as that is documented as creating "an unsigned,
## annotated tag object" in the git-tag(1) manpage. `-s` is sufficient to make
## an annotated, signed tag.
"${git_signing_command_wrapper[@]}" tag -s -m 'Signed by sign-tag-head' "${signed_tag}"
printf '%s\n' "${BASH_SOURCE[0]}: tagged ${context_label} as ${signed_tag}"
