#!/usr/bin/env bash
# =============================================================================
# onx-git-status — Inspect repo HEAD / ahead-behind / dirty state
#
# Input:  { "username":"onx_xxxx", "path":"/home/<user>/repos/foo" }
# Output:
#   {
#     "path":"...", "branch":"main",
#     "last_commit_sha":"...","last_commit_message":"...",
#     "last_commit_author":"...","last_commit_date":"ISO8601",
#     "ahead":0, "behind":0,
#     "dirty_files": 0, "untracked_files": 0,
#     "status": "clean" | "dirty" | "ahead" | "behind" | "diverged"
#   }
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail
# Deployed to: /usr/local/onoxsoft/bin/onx-git-status
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
source "${SCRIPT_DIR}/_lib/common.sh"

require_cmd jq
require_cmd git

INPUT=$(cat)
onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
DEST=$(onx_json_get    "${INPUT}" "path")

onx_validate_username "${USERNAME}"
id "${USERNAME}" &>/dev/null || onx_die 2 "Linux user does not exist: ${USERNAME}"
[[ -n "${DEST}" ]] || onx_die 1 "path is required"
case "${DEST}" in
    "/home/${USERNAME}"|"/home/${USERNAME}/"*) : ;;
    *) onx_die 1 "path must live under /home/${USERNAME}" ;;
esac
[[ "${DEST}" == *..* ]] && onx_die 1 "path may not contain '..'"
[[ -d "${DEST}/.git" ]] || onx_die 2 "not a git repo: ${DEST}"

SHA=$(su -s /bin/bash "${USERNAME}" -c "git -C '${DEST}' rev-parse HEAD 2>/dev/null" || echo "")
BR=$(su -s /bin/bash "${USERNAME}" -c "git -C '${DEST}' rev-parse --abbrev-ref HEAD 2>/dev/null" || echo "main")
MSG=$(su -s /bin/bash "${USERNAME}" -c "git -C '${DEST}' log -1 --pretty=%s 2>/dev/null" || echo "")
AUTHOR=$(su -s /bin/bash "${USERNAME}" -c "git -C '${DEST}' log -1 --pretty=%an 2>/dev/null" || echo "")
ISO=$(su -s /bin/bash "${USERNAME}" -c "git -C '${DEST}' log -1 --pretty=%cI 2>/dev/null" || echo "")

AHEAD_BEHIND=$(su -s /bin/bash "${USERNAME}" -c \
    "git -C '${DEST}' rev-list --left-right --count HEAD...@{upstream} 2>/dev/null" || echo "0	0")
AHEAD=$(echo "${AHEAD_BEHIND}" | awk '{print $1}'); AHEAD=${AHEAD:-0}
BEHIND=$(echo "${AHEAD_BEHIND}" | awk '{print $2}'); BEHIND=${BEHIND:-0}

DIRTY=$(su -s /bin/bash "${USERNAME}" -c \
    "git -C '${DEST}' diff --name-only 2>/dev/null | wc -l" || echo 0)
UNTRACKED=$(su -s /bin/bash "${USERNAME}" -c \
    "git -C '${DEST}' ls-files --others --exclude-standard 2>/dev/null | wc -l" || echo 0)

STATUS="clean"
if (( DIRTY > 0 || UNTRACKED > 0 )); then
    STATUS="dirty"
elif (( AHEAD > 0 && BEHIND > 0 )); then
    STATUS="diverged"
elif (( AHEAD > 0 )); then
    STATUS="ahead"
elif (( BEHIND > 0 )); then
    STATUS="behind"
fi

MSG_J=$(printf '%s' "${MSG}"    | jq -Rs '.')
AUT_J=$(printf '%s' "${AUTHOR}" | jq -Rs '.')
ISO_J=$(printf '%s' "${ISO}"    | jq -Rs '.')

printf '{"path":"%s","branch":"%s","last_commit_sha":"%s","last_commit_message":%s,"last_commit_author":%s,"last_commit_date":%s,"ahead":%s,"behind":%s,"dirty_files":%s,"untracked_files":%s,"status":"%s"}\n' \
    "${DEST}" "${BR}" "${SHA}" "${MSG_J}" "${AUT_J}" "${ISO_J}" "${AHEAD}" "${BEHIND}" "${DIRTY}" "${UNTRACKED}" "${STATUS}"
