#!/bin/bash
# =============================================================================
# wcag-setup.sh
# One-time setup script for the WCAG accessibility scanning extension
# for Watch My Domains SED.
#
# Download this script from:
#   https://learn.domainpunch.com/static/downloads/wcag-setup.sh
#
# This script:
#   1. Installs @axe-core/puppeteer into the existing Node/Puppeteer folder
#   2. Copies axe-scan.js from the tools/wcag/ folder to the Node folder
#   3. Optionally adds a cron job for automatic scanning (see CONFIGURATION)
#
# Requirements:
#   - Watch My Domains SED must already be installed
#   - Node.js and Puppeteer must already be installed (done by the WMD SED
#     install script automatically)
#   - This script must be run as the wmdsed user or as root
#
# Usage:
#   bash wcag-setup.sh
#   bash wcag-setup.sh --dry-run
#
# For non-standard installations, edit the CONFIGURATION block below before
# running.
#
# NOTE ABOUT LINE ENDINGS
#   This script must be saved with Unix LF line endings, not Windows CRLF.
#   If edited on Windows and uploaded with CRLF endings, Bash may fail with
#   errors such as:
#     $'\r': command not found
#     invalid option name: pipefail
#
#   To fix on Linux:
#     dos2unix wcag-setup.sh
#
#   Or:
#     sed -i 's/\r$//' wcag-setup.sh
# =============================================================================

# =============================================================================
# CONFIGURATION
# Edit these values if your WMD SED installation is not in the standard location,
# or to adjust the cron job settings before running.
# Standard installation (created by the WMD SED install script):
#   WMD root : /home/wmdsed/sites/wmdsed60
#   Node dir : /home/wmdsed/webdata
# =============================================================================

WMD_ROOT="/home/wmdsed/sites/wmdsed60"
NODE_DIR="/home/wmdsed/webdata"

# Set to "true" to add a cron job for automatic scanning.
# Set to "false" to skip cron setup entirely.
INSTALL_CRON="true"

# How often to run the scan (cron schedule format).
CRON_SCHEDULE="*/30 * * * *"

# Number of domains to scan in parallel per cron run.
CRON_BATCH="3"

# =============================================================================
# Do not edit below this line
# =============================================================================

DRY_RUN=false

for arg in "$@"; do
    key="${arg%%=*}"
    val="${arg#*=}"
    key_lower=$(echo "$key" | tr '[:upper:]' '[:lower:]' | sed 's/^-*//')
    case "$key_lower" in
        dry-run) DRY_RUN=true ;;
        wmd-root) WMD_ROOT="$val" ;;
        node-dir) NODE_DIR="$val" ;;
    esac
done

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
info()    { echo "[INFO]  $1"; }
warn()    { echo "[WARN]  $1"; }
success() { echo "[OK]    $1"; }
fail()    { echo "[ERROR] $1"; exit 1; }
divider() { echo "========================================================================"; }

divider
info "WCAG Extension Setup for Watch My Domains SED"
divider

if [ "$DRY_RUN" = true ]; then
    warn "DRY RUN mode - no changes will be made."
    divider
fi

# ---------------------------------------------------------------------------
# Pre-flight: resolve and verify all paths before doing anything
# ---------------------------------------------------------------------------
info "Checking paths..."

# Resolve NODE_DIR through symlink if needed
NODE_DIR_REAL=$(readlink -f "$NODE_DIR" 2>/dev/null || echo "$NODE_DIR")

WCAG_TOOLS_DIR="$WMD_ROOT/tools/wcag"
AXE_SOURCE="$WCAG_TOOLS_DIR/axe-scan.js"
AXE_DEST="$NODE_DIR_REAL/axe-scan.js"
NODE_MODULES="$NODE_DIR_REAL/node_modules"
AXE_MODULE="$NODE_MODULES/@axe-core/puppeteer"

echo ""
info "WMD SED root    : $WMD_ROOT"
info "WCAG tools dir  : $WCAG_TOOLS_DIR"
info "Node dir        : $NODE_DIR_REAL"
info "axe-scan.js src : $AXE_SOURCE"
info "axe-scan.js dst : $AXE_DEST"
echo ""

PREFLIGHT_OK=true

if [ ! -d "$WMD_ROOT" ]; then
    warn "WMD SED root not found: $WMD_ROOT"
    warn "Edit the WMD_ROOT variable at the top of this script."
    PREFLIGHT_OK=false
else
    success "WMD SED root found."
fi

if [ ! -d "$WCAG_TOOLS_DIR" ]; then
    warn "WCAG tools folder not found: $WCAG_TOOLS_DIR"
    warn "Ensure the WCAG tools are installed in $WMD_ROOT/tools/wcag/"
    PREFLIGHT_OK=false
else
    success "WCAG tools folder found."
fi

if [ ! -f "$AXE_SOURCE" ]; then
    warn "axe-scan.js not found at: $AXE_SOURCE"
    warn "Ensure axe-scan.js is present in $WCAG_TOOLS_DIR"
    PREFLIGHT_OK=false
else
    success "axe-scan.js source found."
fi

if [ ! -d "$NODE_DIR_REAL" ]; then
    warn "Node directory not found: $NODE_DIR_REAL"
    warn "Edit the NODE_DIR variable at the top of this script."
    PREFLIGHT_OK=false
else
    success "Node directory found."
fi

if [ ! -d "$NODE_MODULES" ]; then
    warn "node_modules not found in $NODE_DIR_REAL"
    warn "Puppeteer must be installed before running this script."
    PREFLIGHT_OK=false
else
    success "node_modules found."
fi

if [ "$PREFLIGHT_OK" = false ]; then
    divider
    fail "Pre-flight checks failed. Correct the issues above and re-run."
fi

# ---------------------------------------------------------------------------
# Check node and npm
# ---------------------------------------------------------------------------
divider
if ! command -v node &>/dev/null; then
    fail "node is not available in PATH."
fi
success "Node.js found: $(node --version)"

if ! command -v npm &>/dev/null; then
    fail "npm is not available in PATH."
fi
success "npm found: $(npm --version)"

# ---------------------------------------------------------------------------
# Install @axe-core/puppeteer if needed
# ---------------------------------------------------------------------------
divider
if [ -d "$AXE_MODULE" ]; then
    EXISTING_VERSION=$(node -e "try{console.log(require('$AXE_MODULE/package.json').version)}catch(e){console.log('unknown')}")
    success "@axe-core/puppeteer already installed (version $EXISTING_VERSION)."
else
    info "Installing @axe-core/puppeteer into $NODE_DIR_REAL ..."
    if [ "$DRY_RUN" = true ]; then
        warn "DRY RUN - would run: cd \"$NODE_DIR_REAL\" && npm install @axe-core/puppeteer --save"
    else
        cd "$NODE_DIR_REAL" || fail "Could not cd to $NODE_DIR_REAL"
        npm install @axe-core/puppeteer --save
        if [ -d "$AXE_MODULE" ]; then
            success "@axe-core/puppeteer installed successfully."
        else
            fail "Installation appeared to complete but module not found. Check npm output above."
        fi
    fi
fi

# ---------------------------------------------------------------------------
# Copy axe-scan.js to Node folder if not already present
# ---------------------------------------------------------------------------
divider
if [ -f "$AXE_DEST" ]; then
    success "axe-scan.js already present at $AXE_DEST"
else
    if [ "$DRY_RUN" = true ]; then
        warn "DRY RUN - would copy $AXE_SOURCE to $AXE_DEST"
    else
        cp "$AXE_SOURCE" "$AXE_DEST"
        if [ -f "$AXE_DEST" ]; then
            success "axe-scan.js copied to $AXE_DEST"
        else
            fail "Copy appeared to succeed but axe-scan.js not found at destination."
        fi
    fi
fi

# ---------------------------------------------------------------------------
# Cron job
# ---------------------------------------------------------------------------
divider
GATHER_PHP="$WMD_ROOT/tools/wcag/wcag-gather.php"
CRON_LOG="$NODE_DIR_REAL/../logs/wmdsed/wcag-cron.log"
CRON_ENTRY="$CRON_SCHEDULE php $GATHER_PHP --batch=$CRON_BATCH >> $CRON_LOG 2>&1"

if [ "$INSTALL_CRON" = "true" ]; then
    # Check if entry already exists
    if crontab -l 2>/dev/null | grep -qF "$GATHER_PHP"; then
        success "Cron job already exists - no changes made."
        crontab -l 2>/dev/null | grep "$GATHER_PHP" | while read -r line; do
            info "  Existing entry: $line"
        done
    else
        if [ "$DRY_RUN" = true ]; then
            warn "DRY RUN - would add cron entry:"
            warn "  $CRON_ENTRY"
        else
            ( crontab -l 2>/dev/null; echo "$CRON_ENTRY" ) | crontab -
            if crontab -l 2>/dev/null | grep -qF "$GATHER_PHP"; then
                success "Cron job added:"
                info "  $CRON_ENTRY"
            else
                warn "Could not verify cron entry was added - check crontab manually."
            fi
        fi
    fi
else
    info "Cron setup skipped (INSTALL_CRON is not set to true)."
    info "To add the cron job manually, run: crontab -e"
    info "And add: $CRON_ENTRY"
fi

# ---------------------------------------------------------------------------
# Done
# ---------------------------------------------------------------------------
divider
if [ "$DRY_RUN" = true ]; then
    warn "DRY RUN complete - no changes were made."
else
    success "Setup complete."
fi
info "Next steps:"
info "  1. Create custom columns:"
info "     php $GATHER_PHP --setup-columns"
info "  2. Create a WMD category named 'WCAG Test Domains' and assign domains to it"
info "  3. Run a dry run to verify:"
info "     php $GATHER_PHP --dry-run"
info "  4. Run the first scan:"
info "     php $GATHER_PHP"
divider