#!/usr/bin/env bash
set -euo pipefail

# ======================================================================
# Arguments
# ======================================================================

CHANGED_FILES="${1:-changed_files.txt}"
OUTPUT_FILE="${2:-text_files.txt}"
FILE_EXTS="${3:-}"             # override whitelist extensions
CLI_EXCLUDES="${4:-}"         # override exclusion paths
CLI_MAX_SIZE="${5:-}"         # override max size per file (bytes)

# ======================================================================
# Extension whitelist (default)
# ======================================================================

DEFAULT_EXTS="c,cpp,h,hpp,py,js,jsx,ts,tsx,java,cs,go,rb,php,rs,kt,scala,sh,bash,zsh,ps1,tf,tfvars,yaml,yml,json,ini,conf,properties,toml,xml,gradle,m,mm,sql,md,rst,txt"

if [ -n "$FILE_EXTS" ]; then
    EXTS_RAW="$FILE_EXTS"
elif [ -n "${TEXT_FILE_EXTS:-}" ]; then
    EXTS_RAW="$TEXT_FILE_EXTS"
else
    EXTS_RAW="$DEFAULT_EXTS"
fi

IFS=',' read -ra EXT_WHITELIST <<< "$(echo "$EXTS_RAW" | tr '[:upper:]' '[:lower:]' | tr -d ' ')"

# ======================================================================
# Exclusions paths
# ======================================================================

if [[ -n "$CLI_EXCLUDES" ]]; then
    EXCLUDES_RAW="$CLI_EXCLUDES"
elif [[ -n "${SCAN_EXCLUDE_PATHS:-}" ]]; then
    EXCLUDES_RAW="$SCAN_EXCLUDE_PATHS"
else
    EXCLUDES_RAW=""
fi

IFS=',' read -ra EXCLUDE_PATHS <<< "$(echo "$EXCLUDES_RAW" | tr -d ' ')"

# ======================================================================
# Maximum file-size limit
# ======================================================================

if [[ -n "$CLI_MAX_SIZE" ]]; then
    MAX_SIZE="$CLI_MAX_SIZE"
elif [[ -n "${MAX_SCAN_FILE_BYTES:-}" ]]; then
    MAX_SIZE="$MAX_SCAN_FILE_BYTES"
else
    MAX_SIZE="0"  # 0 = no limit
fi

# ======================================================================
# Special no-extension text files
# ======================================================================

SPECIAL_NAMES=(
    "dockerfile"
    "makefile"
    ".gitignore"
    ".gitattributes"
    ".editorconfig"
)

echo "[INFO] Extension whitelist: ${EXT_WHITELIST[*]}"
echo "[INFO] Exclusion paths: ${EXCLUDE_PATHS[*]}"
echo "[INFO] Max allowed file size (bytes): ${MAX_SIZE}"
echo "[INFO] Special text files: ${SPECIAL_NAMES[*]}"

> "$OUTPUT_FILE"

# ======================================================================
# Helper: Check if file should be excluded by path
# ======================================================================
should_exclude_path() {
    local path="$1"
    for ex in "${EXCLUDE_PATHS[@]}"; do
        [[ -z "$ex" ]] && continue
        if [[ "$path" == "$ex"* ]]; then
            return 0  # true -> excluded
        fi
    done
    return 1  # false -> not excluded
}

# ======================================================================
# Helper: Check file size against MAX_SIZE
# ======================================================================
is_too_large() {
    local file="$1"
    local size
    size=$(wc -c < "$file" | tr -d ' ')
    if [ $MAX_SIZE -gt 0 ] && [ $size -gt $MAX_SIZE ]; then
        echo "[DEBUG] Excluded due to size ($size > $MAX_SIZE): $file"
        return 0
    fi
    return 1
}

# ======================================================================
# Main loop
# ======================================================================
while IFS= read -r FILEPATH; do
    [[ -z "$FILEPATH" ]] && continue

    # Skip files that do not exist
    [[ ! -f "$FILEPATH" ]] && continue

    # 1. Path exclusion
    if should_exclude_path "$FILEPATH"; then
        echo "[DEBUG] Excluded by path: $FILEPATH"
        continue
    fi

    BASENAME="$(basename "$FILEPATH")"
    BASENAME_LC="$(echo "$BASENAME" | tr '[:upper:]' '[:lower:]')"

    # 2. Special file names
    for special in "${SPECIAL_NAMES[@]}"; do
        if [[ "$BASENAME_LC" == "$special" ]]; then
            if is_too_large "$FILEPATH"; then continue; fi
            echo "$FILEPATH" >> "$OUTPUT_FILE"
            continue 2
        fi
    done

    # 3. Extract extension
    if [[ "$FILEPATH" == *.* ]]; then
        EXT="${FILEPATH##*.}"
    else
        EXT=""
    fi

    EXT_LC="$(echo "$EXT" | tr '[:upper:]' '[:lower:]')"

    # 4. If no extension: skip (specials already handled)
    if [[ -z "$EXT_LC" ]]; then
        continue
    fi

    # 5. If not in whitelist: skip
    in_whitelist=false
    for allowed in "${EXT_WHITELIST[@]}"; do
        if [[ "$EXT_LC" == "$allowed" ]]; then
            in_whitelist=true
            break
        fi
    done

    [[ "$in_whitelist" == false ]] && continue

    # 6. File size check
    if is_too_large "$FILEPATH"; then
        continue
    fi

    # 7. Add to output
    echo "$FILEPATH" >> "$OUTPUT_FILE"

done < "$CHANGED_FILES"

# ======================================================================
# Summary
# ======================================================================
COUNT=$(wc -l < "$OUTPUT_FILE" | tr -d ' ')
echo "[INFO] Filter complete → $COUNT files selected"