#!/bin/bash

. "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/utils.sh

# Helper function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to set up the temporary staging area
temp_staging_setup() {
    if [ -e "$TMP_STAGING" ]; then
        rm -rf "$TMP_STAGING"
    fi
    mkdir "$TMP_STAGING"
}

# Function to clean up the temporary staging area
temp_staging_cleanup() {
    rm -rf "$TMP_STAGING"
}

# Function to retrieve staged files
retrieve_staged_files() {
    if git rev-parse --verify HEAD >/dev/null 2>&1; then
        against=HEAD
    else
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
    fi
    git diff-index --name-only --cached --diff-filter=ACMR "$against"
}

# Function to copy staged files to temporary directory
copy_staged_files() {
    local files="$1"
    for FILE in $files; do
        ID=$(git ls-files -s "$FILE" | awk '{print $2}')
        mkdir -p "$TMP_STAGING/$(dirname "$FILE")"
        git show :"$FILE" > "$TMP_STAGING/$FILE"
    done
}

# Function to run PHP CodeSniffer on the temporary staging folder
run_phpcs_on_staging() {
  $PHPCS_BIN "$TMP_STAGING" --extensions=php
  if [ $? != 0 ]; then
      echo -e "\033[31m❌ PHP CodeSniffer found issues in the staged files.\033[0m"
      error_alert
  fi
}

# Function to process files (DRY principle applied)
process_files() {
    local files="$1"
    local process_function="$2"
    for FILE in $files; do
        if [[ $FILE != *.js ]]; then
            $process_function "$FILE"
        fi
    done
}

# Function to run PHP linting on a file
php_lint_file() {
    local file="$1"
    php -l -d display_errors=0 "$TMP_STAGING/$file"
    if [ $? != 0 ]; then
        echo -e "\033[31m❌ PHP Lint found issues in $file. Fix the error before commit.\033[0m"
        error_alert
    fi
}

# ----------------------------------------------------------------------
# Main script execution
# ----------------------------------------------------------------------
CONFIG_FILE=$(dirname $0)/config
if [ -e "$CONFIG_FILE" ]; then
    . "$CONFIG_FILE"
fi

# Check if PHP CodeSniffer is available
if ! $PHPCS_BIN --version >/dev/null 2>&1; then
    echo -e "\033[31m❌ PHP CodeSniffer command could not be run -> $PHPCS_BIN. Try to install composer dependencies.\033[0m"
    error_alert
fi

# Retrieve staged files
FILES=$(retrieve_staged_files)
if [ -z "$FILES" ]; then
    exit 0
fi

# Set up temporary staging area
temp_staging_setup

# Copy staged files to temporary directory
copy_staged_files "$FILES"

LOCAL_PATH=$(pwd)
# If a project-specific pre-commit hook exists, run it instead of the default one
if [ -f "$LOCAL_PATH/hooks/pre-commit" ]; then
  print_heading "Running project-specific pre-commit hook..."

  "$LOCAL_PATH"/hooks/pre-commit "$TMP_STAGING"
  if [ $? != 0 ]; then
    exit 1
  fi
else
  # Run the default pre-commit hook
  print_heading "Running lib-velis pre-commit hook..."

  # Run PHP CodeSniffer on the entire temporary staging folder
  print_heading "Running PHP CodeSniffer..."
  run_phpcs_on_staging

  # Run PHP linting
  print_heading "Checking PHP Lint..."
  process_files "$FILES" php_lint_file
fi

# Clean up
temp_staging_cleanup
exit 0
