#!/bin/bash
# -*- coding: utf-8 -*-
# Timestamp: "2025-11-11 07:23:33 (ywatanabe)"
# File: ./scripts/shell/modules/check_dependancy_commands.sh

ORIG_DIR="$(pwd)"
THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_PATH="$THIS_DIR/.$(basename "$0").log"
echo >"$LOG_PATH"

GRAY='\033[0;90m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

echo_info() { echo -e "${GRAY}INFO: $1${NC}"; }
log_info() {
    if [ "${SCITEX_LOG_LEVEL:-1}" -ge 2 ]; then
        echo -e "  \033[0;90m→ $1\033[0m"
    fi
}
echo_success() { echo -e "${GREEN}SUCC: $1${NC}"; }
echo_warning() { echo -e "${YELLOW}WARN: $1${NC}"; }
echo_error() { echo -e "${RED}ERRO: $1${NC}"; }
echo_header() { echo_info "=== $1 ==="; }
# ---------------------------------------

# Don't clear log at start - timing info will be appended

# Configurations
source ./config/load_config.sh "$SCITEX_WRITER_DOC_TYPE"

# Source the 00_shared LaTeX commands module
source "$(dirname "${BASH_SOURCE[0]}")/command_switching.src"
log_info "Running ${BASH_SOURCE[0]}..."

# Detect package manager
detect_package_manager() {
    if command -v apt &>/dev/null; then
        echo "apt"
    elif command -v yum &>/dev/null; then
        echo "yum"
    else
        echo "unknown"
    fi
}

# Check if sudo is available
has_sudo() {
    if command -v sudo &>/dev/null; then
        return 0
    else
        return 1
    fi
}

PKG_MANAGER=$(detect_package_manager)
SUDO_PREFIX=""
if has_sudo; then
    SUDO_PREFIX="sudo "
fi

# Standalone checker for each tool
check_pdflatex() {
    local cmd
    cmd=$(get_cmd_pdflatex "$ORIG_DIR")
    if [ -z "$cmd" ]; then
        echo "- pdflatex"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - ${SUDO_PREFIX}apt install texlive-latex-base"
        elif [ "$PKG_MANAGER" = "yum" ]; then
            echo "    - ${SUDO_PREFIX}yum install texlive-latex"
        fi
        echo "    - Or use: module load texlive"
        echo "    - Or use: apptainer/singularity with texlive container"
        return 1
    fi
    return 0
}

check_bibtex() {
    local cmd
    cmd=$(get_cmd_bibtex "$ORIG_DIR")
    if [ -z "$cmd" ]; then
        echo "- bibtex"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - ${SUDO_PREFIX}apt install texlive-bibtex-extra"
        elif [ "$PKG_MANAGER" = "yum" ]; then
            echo "    - ${SUDO_PREFIX}yum install texlive-bibtex"
        fi
        echo "    - Or use: module load texlive"
        echo "    - Or use: apptainer/singularity with texlive container"
        return 1
    fi
    return 0
}

check_latexdiff() {
    local cmd
    cmd=$(get_cmd_latexdiff "$ORIG_DIR")
    if [ -z "$cmd" ]; then
        echo "- latexdiff"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - ${SUDO_PREFIX}apt install latexdiff"
        elif [ "$PKG_MANAGER" = "yum" ]; then
            echo "    - ${SUDO_PREFIX}yum install texlive-latexdiff"
        fi
        echo "    - Or use: module load texlive"
        echo "    - Or use: apptainer/singularity with texlive container"
        return 1
    fi
    return 0
}

check_texcount() {
    local cmd
    cmd=$(get_cmd_texcount "$ORIG_DIR")
    if [ -z "$cmd" ]; then
        echo "- texcount"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - ${SUDO_PREFIX}apt install texlive-extra-utils"
        elif [ "$PKG_MANAGER" = "yum" ]; then
            echo "    - ${SUDO_PREFIX}yum install texlive-texcount"
        fi
        echo "    - Or use: module load texlive"
        echo "    - Or use: apptainer/singularity with texlive container"
        return 1
    fi
    return 0
}

check_xlsx2csv() {
    if ! command -v xlsx2csv &>/dev/null && ! python3 -c "import xlsx2csv" &>/dev/null 2>&1; then
        echo "- xlsx2csv"
        echo "    - pip install xlsx2csv"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - Or: ${SUDO_PREFIX}apt install xlsx2csv"
        fi
        return 1
    fi
    return 0
}

check_csv2latex() {
    if ! command -v csv2latex &>/dev/null && ! python3 -c "import csv2latex" &>/dev/null 2>&1; then
        echo "- csv2latex"
        echo "    - pip install csv2latex"
        return 1
    fi
    return 0
}

check_parallel() {
    if ! command -v parallel &>/dev/null; then
        echo "- parallel"
        if [ "$PKG_MANAGER" = "apt" ]; then
            echo "    - ${SUDO_PREFIX}apt install parallel"
        elif [ "$PKG_MANAGER" = "yum" ]; then
            echo "    - ${SUDO_PREFIX}yum install parallel"
        fi
        return 1
    fi
    return 0
}

check_opencv() {
    if command -v python3 &>/dev/null; then
        if ! python3 -c "import cv2" &>/dev/null 2>&1; then
            echo "- opencv-python (optional, for --crop_tif)"
            echo "    - pip install opencv-python"
            return 1
        fi
    fi
    return 0
}

check_numpy() {
    if command -v python3 &>/dev/null; then
        if ! python3 -c "import numpy" &>/dev/null 2>&1; then
            echo "- numpy (optional, for --crop_tif)"
            echo "    - pip install numpy"
            return 1
        fi
    fi
    return 0
}

check_mmdc() {
    local cmd
    cmd=$(get_cmd_mmdc "$ORIG_DIR")
    if [ -z "$cmd" ]; then
        echo "- mmdc (optional, for Mermaid diagrams)"
        if ! command -v npm &>/dev/null; then
            echo "    - First install npm/nodejs"
        fi
        echo "    - npm install -g @mermaid-js/mermaid-cli"
        echo "    - Or use: apptainer/singularity with mermaid container"
        return 1
    fi
    return 0
}

check_bibtexparser() {
    if command -v python3 &>/dev/null; then
        if ! python3 -c "import bibtexparser" &>/dev/null 2>&1; then
            echo "- bibtexparser (for bibliography analysis tools)"
            echo "    - pip install bibtexparser"
            return 1
        fi
    fi
    return 0
}

# Check all required commands (parallelized for speed)
check_all_dependencies() {
    local has_missing_required=false
    local has_missing_optional=false
    local required_output=""
    local optional_output=""

    # Log run timestamp
    echo "=== $(date '+%Y-%m-%d %H:%M:%S') ===" >>"$LOG_PATH"

    # Quick native-only check to avoid expensive container warmup
    local all_native_available=true
    local start_native_check
    start_native_check=$(date +%s%N)

    # Check if all required native commands exist (fast check only)
    if ! command -v pdflatex &>/dev/null || ! pdflatex --version &>/dev/null 2>&1; then
        all_native_available=false
    elif ! command -v bibtex &>/dev/null || ! bibtex --version &>/dev/null 2>&1; then
        all_native_available=false
    elif ! command -v latexdiff &>/dev/null; then
        all_native_available=false
    elif ! command -v texcount &>/dev/null || ! texcount --version &>/dev/null 2>&1; then
        all_native_available=false
    fi

    local end_native_check
    end_native_check=$(date +%s%N)
    local native_check_ms
    native_check_ms=$(((end_native_check - start_native_check) / 1000000))
    echo "Native check: ${native_check_ms}ms" >>"$LOG_PATH"
    echo_info "    Native check: ${native_check_ms}ms"

    # Only do expensive warmup if native commands are missing
    if [ "$all_native_available" = false ]; then
        echo_info "    Native commands incomplete, checking alternatives..."
        # Pre-warmup: do expensive shared setup once before parallelizing
        # This prevents each parallel job from doing redundant work
        local start_warmup
        start_warmup=$(date +%s%N)
        get_container_runtime &>/dev/null
        load_texlive_module &>/dev/null
        setup_latex_container &>/dev/null
        setup_mermaid_container &>/dev/null
        local end_warmup
        end_warmup=$(date +%s%N)
        local warmup_ms
        warmup_ms=$(((end_warmup - start_warmup) / 1000000))
        echo "Warmup: ${warmup_ms}ms" >>"$LOG_PATH"
        echo_info "    Warmup: ${warmup_ms}ms"
    else
        echo_info "    All native LaTeX commands available (skipping container warmup)"
    fi

    # Temp directory for parallel results
    local temp_dir
    temp_dir=$(mktemp -d)

    # Run all required checks in parallel, capturing exit codes
    local start_checks
    start_checks=$(date +%s%N)
    (
        check_pdflatex >"$temp_dir/req_pdflatex" 2>&1
        echo $? >"$temp_dir/req_pdflatex.exit"
    ) &
    (
        check_bibtex >"$temp_dir/req_bibtex" 2>&1
        echo $? >"$temp_dir/req_bibtex.exit"
    ) &
    (
        check_latexdiff >"$temp_dir/req_latexdiff" 2>&1
        echo $? >"$temp_dir/req_latexdiff.exit"
    ) &
    (
        check_texcount >"$temp_dir/req_texcount" 2>&1
        echo $? >"$temp_dir/req_texcount.exit"
    ) &
    (
        check_xlsx2csv >"$temp_dir/req_xlsx2csv" 2>&1
        echo $? >"$temp_dir/req_xlsx2csv.exit"
    ) &
    (
        check_csv2latex >"$temp_dir/req_csv2latex" 2>&1
        echo $? >"$temp_dir/req_csv2latex.exit"
    ) &
    (
        check_parallel >"$temp_dir/req_parallel" 2>&1
        echo $? >"$temp_dir/req_parallel.exit"
    ) &
    (
        check_bibtexparser >"$temp_dir/req_bibtexparser" 2>&1
        echo $? >"$temp_dir/req_bibtexparser.exit"
    ) &

    # Run all optional checks in parallel
    (
        check_opencv >"$temp_dir/opt_opencv" 2>&1
        echo $? >"$temp_dir/opt_opencv.exit"
    ) &
    (
        check_numpy >"$temp_dir/opt_numpy" 2>&1
        echo $? >"$temp_dir/opt_numpy.exit"
    ) &
    (
        check_mmdc >"$temp_dir/opt_mmdc" 2>&1
        echo $? >"$temp_dir/opt_mmdc.exit"
    ) &

    # Wait for all background jobs
    wait
    local end_checks
    end_checks=$(date +%s%N)
    local checks_ms
    checks_ms=$(((end_checks - start_checks) / 1000000))
    echo "Parallel checks: ${checks_ms}ms" >>"$LOG_PATH"
    echo_info "    Parallel checks: ${checks_ms}ms"

    # Collect required results with exit codes
    declare -A tool_status
    local exit_code
    for tool in pdflatex bibtex latexdiff texcount xlsx2csv csv2latex parallel bibtexparser; do
        exit_code=$(cat "$temp_dir/req_${tool}.exit" 2>/dev/null || echo 1)
        if [ "$exit_code" -eq 0 ]; then
            tool_status[$tool]="✓"
        else
            has_missing_required=true
            tool_status[$tool]="✗"
            if [ -s "$temp_dir/req_${tool}" ]; then
                required_output="${required_output}$(cat "$temp_dir/req_${tool}")\n"
            fi
        fi
    done

    # Collect optional results
    local tool
    for result_file in "$temp_dir"/opt_*.exit; do
        tool=$(basename "$result_file" .exit | sed 's/opt_//')
        exit_code=$(cat "$result_file" 2>/dev/null || echo 1)
        if [ "$exit_code" -ne 0 ]; then
            has_missing_optional=true
            if [ -s "${result_file%.exit}" ]; then
                optional_output="${optional_output}$(cat "${result_file%.exit}")\n"
            fi
        fi
    done

    # Cleanup
    rm -rf "$temp_dir"

    # Display results
    if [ "$has_missing_required" = true ]; then
        echo_error "    Missing required tools:"
        echo -e "$required_output"
        return 1
    else
        # Show summary table using cached results (no additional checks!)
        echo_success "    Required tools:"
        printf "      %-20s %s\n" "pdflatex" "${tool_status[pdflatex]}"
        printf "      %-20s %s\n" "bibtex" "${tool_status[bibtex]}"
        printf "      %-20s %s\n" "latexdiff" "${tool_status[latexdiff]}"
        printf "      %-20s %s\n" "texcount" "${tool_status[texcount]}"
        printf "      %-20s %s\n" "xlsx2csv" "${tool_status[xlsx2csv]}"
        printf "      %-20s %s\n" "csv2latex" "${tool_status[csv2latex]}"
        printf "      %-20s %s\n" "parallel" "${tool_status[parallel]}"
        printf "      %-20s %s\n" "bibtexparser" "${tool_status[bibtexparser]}"
    fi

    if [ "$has_missing_optional" = true ]; then
        echo_warning "    Missing optional tools:"
        echo -e "$optional_output"
    fi

    return 0
}

# Run checks
check_all_dependencies
exit_code=$?

exit $exit_code

# EOF
