#!/usr/bin/env bash

set -euo pipefail

echo "Running pre-commit checks..."

raw_staged_kotlin_files=()
staged_kotlin_files=()
ignored_missing_files=()

while IFS= read -r -d '' file; do
  raw_staged_kotlin_files+=("$file")
done < <(git diff --cached --name-only --diff-filter=ACMR -z -- '*.kt')

for file in "${raw_staged_kotlin_files[@]}"; do
  if [ -f "$file" ]; then
    staged_kotlin_files+=("$file")
  else
    ignored_missing_files+=("$file")
  fi
done

if [ ${#ignored_missing_files[@]} -ne 0 ]; then
  echo ""
  echo "Ignoring staged Kotlin paths that no longer exist:"
  printf '  - %s\n' "${ignored_missing_files[@]}"
fi

if [ ${#staged_kotlin_files[@]} -eq 0 ]; then
  echo "No existing staged Kotlin files found. Skipping ktlint/detekt pre-commit checks."
  exit 0
fi

echo ""
echo "Existing staged Kotlin files passed to Gradle:"
printf '  - %s\n' "${staged_kotlin_files[@]}"

partially_staged_files=()

for file in "${staged_kotlin_files[@]}"; do
  if ! git diff --quiet -- "$file"; then
    partially_staged_files+=("$file")
  fi
done

if [ ${#partially_staged_files[@]} -ne 0 ]; then
  echo ""
  echo "Commit blocked."
  echo "Some staged Kotlin files also have unstaged changes."
  echo "This hook auto-stages files changed by ktlintFormat, so partial staging is unsafe."
  echo ""
  echo "Please fully stage or revert unstaged changes in these files first:"
  printf '  - %s\n' "${partially_staged_files[@]}"
  echo ""
  echo "Then try staging and committing again."
  exit 1
fi

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

printf '%s\n' "${staged_kotlin_files[@]}" > "$precommit_files_file"

run_gradle_task() {
  local task_name="$1"

  echo ""
  echo "Running $task_name..."

  if ! ./gradlew \
    --no-configuration-cache \
    --no-build-cache \
    -Pprecommit=true \
    -PprecommitFiles="$precommit_files_file" \
    "$task_name"; then
    echo ""
    echo "Commit blocked."
    echo "$task_name failed."
    echo "Please fix the reported issues, stage your changes, and try committing again."
    exit 1
  fi
}

run_gradle_task "ktlintFormat"

echo ""
echo "Re-staging Kotlin files changed by ktlintFormat..."

for file in "${staged_kotlin_files[@]}"; do
  if [ -f "$file" ]; then
    git add "$file"
  fi
done

run_gradle_task "ktlintCheck"
run_gradle_task "detekt"

echo ""
echo "Pre-commit checks passed."
exit 0