#!/bin/bash

# Default values
DEFAULT_SOURCE_DIR="scripts"
DEFAULT_OUTPUT_FILE="output.txt"
DEFAULT_TEE_DEST="\$DEST/.config/qtile/scripts"

# Usage message
usage() {
  cat <<USAGE_EOF
Usage: $(basename "$0") [OPTIONS]

Wraps non-binary files from a source directory into heredoc functions
and outputs them to a single file.

OPTIONS:
    -s, --source DIR       Source directory containing files (default: $DEFAULT_SOURCE_DIR)
    -o, --output FILE      Output file path (default: $DEFAULT_OUTPUT_FILE)
    -t, --tee-dest PATH    Destination path for tee commands (default: $DEFAULT_TEE_DEST)
    -h, --help             Show this help message

EXAMPLES:
    $(basename "$0") -s ./my-scripts
    $(basename "$0") -s ./my-scripts -o bundle.sh -t /home/user/config

USAGE_EOF
  exit "${1:-0}"
}

# Show usage if no arguments provided
if [[ $# -eq 0 ]]; then
  usage 0
fi

# Parse command-line arguments
SOURCE_DIR="$DEFAULT_SOURCE_DIR"
OUTPUT_FILE="$DEFAULT_OUTPUT_FILE"
TEE_DEST="$DEFAULT_TEE_DEST"

while [[ $# -gt 0 ]]; do
  case "$1" in
  -s | --source)
    SOURCE_DIR="$2"
    shift 2
    ;;
  -o | --output)
    OUTPUT_FILE="$2"
    shift 2
    ;;
  -t | --tee-dest)
    TEE_DEST="$2"
    shift 2
    ;;
  -h | --help)
    usage 0
    ;;
  *)
    echo "Error: Unknown option '$1'" >&2
    usage 1
    ;;
  esac
done

# Validate source directory
if [[ ! -d "$SOURCE_DIR" ]]; then
  echo "Error: Source directory '$SOURCE_DIR' does not exist." >&2
  exit 1
fi

# Check if source directory is empty
shopt -s nullglob
files=("$SOURCE_DIR"/*)
shopt -u nullglob

if [[ ${#files[@]} -eq 0 ]]; then
  echo "Error: Source directory '$SOURCE_DIR' is empty." >&2
  exit 1
fi

# Get absolute paths for comparison
OUTPUT_DIR=$(cd "$(dirname "$OUTPUT_FILE")" 2>/dev/null && pwd)
OUTPUT_FILE_ABS="${OUTPUT_DIR}/$(basename "$OUTPUT_FILE")"

# Function to check if file is binary
is_binary() {
  local file="$1"
  file --mime-encoding "$file" 2>/dev/null | grep -q "binary"
}

# Function to create safe identifier from filename
make_safe_identifier() {
  local filename="$1"
  local safe="${filename%.*}"
  safe="${safe//[^a-zA-Z0-9]/_}"
  safe=$(echo "$safe" | sed 's/_\+/_/g; s/^_//; s/_$//')
  echo "$safe"
}

# Clear or create output file
>"$OUTPUT_FILE"

# Counters
processed=0
skipped=0

for filepath in "$SOURCE_DIR"/*; do
  # Skip if not a regular file
  [[ -f "$filepath" ]] || continue

  # Get absolute path of current file
  filepath_dir=$(cd "$(dirname "$filepath")" && pwd)
  filepath_abs="${filepath_dir}/$(basename "$filepath")"

  # Skip the output file if it is in the source directory
  if [[ "$filepath_abs" == "$OUTPUT_FILE_ABS" ]]; then
    echo "Skipping output file: $filepath"
    ((skipped++))
    continue
  fi

  # Skip binary files
  if is_binary "$filepath"; then
    echo "Skipping binary file: $filepath"
    ((skipped++))
    continue
  fi

  # Extract filename and create safe identifier
  filename=$(basename "$filepath")
  safe_id=$(make_safe_identifier "$filename")

  # Create unique heredoc delimiter
  heredoc_delim="EOF_${safe_id}_EOF"

  # Function name
  func_name="conf_print_${safe_id}"

  # Write function definition
  {
    echo "${func_name}() {"
    echo "cat <<'${heredoc_delim}'"
    cat "$filepath"
    echo ""
    echo "${heredoc_delim}"
    echo "}"
    echo "${func_name} | tee \"${TEE_DEST}/${filename}\""
    echo ""
  } >>"$OUTPUT_FILE"

  ((processed++))
  echo "Processed: $filename -> delimiter: $heredoc_delim"
done

echo "----------------------------------------"
echo "Processing complete!"
echo "  Processed: $processed file(s)"
echo "  Skipped:   $skipped file(s)"
echo "  Output:    $OUTPUT_FILE"
