#!/usr/bin/env bash

set -euo pipefail

usage() {
  echo "Usage: $(basename "$0") -c COMMENT_SYMBOL [-e EXCLUDE_PATTERN]... TARGET"
  echo "  -c  Comment symbol (e.g., '#' or '//')"
  echo "  -e  Exclude pattern (can be specified multiple times)"
  echo "  TARGET  File or directory to process"
  exit 1
}

comment_sym=""
excludes=()

while getopts "c:e:h" opt; do
  case $opt in
  c) comment_sym="$OPTARG" ;;
  e) excludes+=("$OPTARG") ;;
  h) usage ;;
  *) usage ;;
  esac
done

shift $((OPTIND - 1))
[[ $# -ne 1 ]] && usage
[[ -z "$comment_sym" ]] && usage

target="$(realpath "$1")"
base_dir="$(pwd)"

process_file() {
  local file="$1"
  # shellcheck disable=SC2295
  local rel_path="${file#$base_dir/}"

  local path_comment="$comment_sym path: $rel_path"

  # Read first two lines
  local line1 line2
  IFS= read -r line1 <"$file" 2>/dev/null || line1=""
  IFS= read -r line2 < <(tail -n +2 "$file") 2>/dev/null || line2=""

  # Handle shebang case
  if [[ "$line1" =~ ^#! ]]; then
    if [[ "$line2" == *"path: "* ]]; then
      # Replace existing path comment on line 2
      {
        echo "$line1"
        echo "$path_comment"
        tail -n +3 "$file"
      } >"$file.tmp"
    else
      # Insert new path comment after shebang
      {
        echo "$line1"
        echo "$path_comment"
        tail -n +2 "$file"
      } >"$file.tmp"
    fi
  else
    if [[ "$line1" == *"path: "* ]]; then
      # Replace existing path comment on line 1
      {
        echo "$path_comment"
        tail -n +2 "$file"
      } >"$file.tmp"
    else
      # Insert new path comment at top
      {
        echo "$path_comment"
        cat "$file"
      } >"$file.tmp"
    fi
  fi

  mv "$file.tmp" "$file"
}

if [[ -f "$target" ]]; then
  process_file "$target"
elif [[ -d "$target" ]]; then
  find_cmd=(find "$target")

  # Always exclude hidden files and directories
  find_cmd+=(\( -name ".*" -prune \))

  if [[ ${#excludes[@]} -gt 0 ]]; then
    find_cmd+=(-o \()
    for i in "${!excludes[@]}"; do
      [[ $i -gt 0 ]] && find_cmd+=(-o)
      find_cmd+=(-path "*/${excludes[$i]}" -prune)
      find_cmd+=(-o -path "*/${excludes[$i]}/*" -prune)
    done
    find_cmd+=(\))
  fi

  find_cmd+=(-o -type f -print0)

  while IFS= read -r -d '' file; do
    process_file "$file"
  done < <("${find_cmd[@]}")
else
  echo "Error: $target is not a file or directory" >&2
  exit 1
fi
