#!/usr/bin/env bash

# Pre-commit hook to automatically update PyTorch commit pin and sync c10 directories when torch_pin.py changes

# Check if torch_pin.py is being committed
if git diff --cached --name-only | grep -q "^torch_pin.py$"; then
    echo "🔍 Detected changes to torch_pin.py"
    echo "📝 Updating PyTorch commit pin and syncing c10 directories..."

    # Run the update script (which now also syncs c10 directories)
    if python .github/scripts/update_pytorch_pin.py; then
        # Stage any modified files (pytorch.txt and grafted c10 files)
        if ! git diff --quiet .ci/docker/ci_commit_pins/pytorch.txt; then
            git add .ci/docker/ci_commit_pins/pytorch.txt
            echo "📌 Staged .ci/docker/ci_commit_pins/pytorch.txt"
        fi

        # Stage any grafted c10 files
        if ! git diff --quiet runtime/core/portable_type/c10/; then
            git add runtime/core/portable_type/c10/
            echo "📌 Staged grafted c10 files"
        fi
    else
        echo "❌ Failed to update PyTorch commit pin"
        echo "Please run: python .github/scripts/update_pytorch_pin.py"
        exit 1
    fi
fi

# --- lintrunner ---

if ! command -v lintrunner >/dev/null 2>&1; then
    echo "Warning: lintrunner not found. Skipping lint checks."
    echo "Install with: pip install lintrunner lintrunner-adapters && lintrunner init"
    exit 0
fi

if [ ! -f .lintrunner.toml ]; then
    echo "Warning: .lintrunner.toml not found. Skipping lint checks."
    exit 0
fi

git_dir=$(git rev-parse --git-dir)

# Portable hash: sha256sum (Linux) or shasum (macOS)
if command -v sha256sum >/dev/null 2>&1; then
    toml_hash=$(sha256sum .lintrunner.toml | cut -d' ' -f1)
else
    toml_hash=$(shasum -a 256 .lintrunner.toml | cut -d' ' -f1)
fi
stored_hash=""
[ -f "${git_dir}/.lintrunner_init_hash" ] && stored_hash=$(cat "${git_dir}/.lintrunner_init_hash")

if [ "${toml_hash}" != "${stored_hash}" ]; then
    echo "Running lintrunner init..."
    if lintrunner init; then
        echo "${toml_hash}" > "${git_dir}/.lintrunner_init_hash"
    else
        echo "lintrunner init failed. Run 'lintrunner init' manually."
        exit 1
    fi
fi

staged_files=$(git diff --cached --name-only --diff-filter=ACMR)

# Use HEAD^ if it exists (skip on initial commit)
revision_flag="--revision HEAD^"
if ! git rev-parse HEAD^ >/dev/null 2>&1; then
    revision_flag=""
fi

lintrunner -a $revision_flag --skip MYPY
lint_status=$?

# Check if lintrunner modified any staged files. If so, block the commit
# so the user can review the changes before committing.
files_modified=0
while IFS= read -r path; do
    [ -z "${path}" ] && continue
    if ! git diff --quiet -- "${path}" 2>/dev/null; then
        files_modified=1
        break
    fi
done <<< "${staged_files}"

if [ $files_modified -eq 1 ]; then
    echo "Lintrunner modified files. Review with 'git diff', then 'git add -u && git commit'."
    exit 1
fi

if [ $lint_status -ne 0 ]; then
    echo "Lint errors found. Fix them and try again, or use 'git commit --no-verify' to skip."
    exit 1
fi
