#!/bin/bash
# ------------------------------------------------------------------
# Author: ChatGPT
# Generated on: $(date '+%Y-%m-%d')
#
# This script recursively creates or updates a table-of-contents README
# file in each non-hidden directory. The file is named "Folder Name - README.md".
#
# Each README includes:
#   - A header with an author/date line.
#   - A header with the folder's name.
#   - An alphabetically sorted list of immediate subdirectories, with links
#     to that subdirectory’s own README.
#   - An alphabetically sorted list of immediate files (excluding the generated README).
#
# Hidden directories (or any directory under a hidden parent such as .git) are skipped.
#
# The script only updates a README if the "body" (everything from line 3 on)
# has changed. It also prints a progress indicator like "[x/y] Updated: {dir}".
# ------------------------------------------------------------------

# Set the base directory (change "." if necessary)
base_dir="."

# Build an array of directories to process.
dirs=()
while IFS= read -r -d '' dir; do
    # Skip directories whose basename starts with a dot or whose path contains "/.git"
    if [[ "$(basename "$dir")" == .* ]] || [[ "$dir" == *"/.git"* ]] || [[ "$dir" == *"/.obsidian"* ]] ; then
        continue
    fi
    dirs+=( "$dir" )
done < <(find "$base_dir" -type d -print0)

total=${#dirs[@]}
count=0

# Process each directory in the array.
for dir in "${dirs[@]}"; do
    count=$((count+1))
    # For the top-level directory, use the actual name (using $PWD); otherwise, use the directory's basename.
    if [ "$dir" = "$base_dir" ]; then
        base=$(basename "$PWD")
    else
        base=$(basename "$dir")
    fi

    # Define the path for the README file: "Folder Name - README.md"
    readme="$dir/${base} - README.md"

    # Create a temporary file to hold the new content.
    tmpfile=$(mktemp)

    # Write the header into the temporary file.
    {
      echo "Generated by ChatGPT on $(date '+%Y-%m-%d')"
      echo ""
      echo "# Table of Contents for ${base}"
      echo ""
    } > "$tmpfile"

    #########################
    # Process Subdirectories
    #########################
    subdirs=()
    while IFS= read -r -d '' subdir; do
        sub_basename=$(basename "$subdir")
        if [ -n "$sub_basename" ]; then
            subdirs+=( "$sub_basename" )
        fi
    done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -print0)
    
    if [ ${#subdirs[@]} -gt 0 ]; then
        # Sort subdirectory names alphabetically.
        mapfile -t sorted_subdirs < <(printf "%s\n" "${subdirs[@]}" | sort)
        echo "## Subdirectories" >> "$tmpfile"
        for sub in "${sorted_subdirs[@]}"; do
            # Link format: [[Subfolder/Subfolder - README]]
            line="- [[${sub}/${sub} - README]]"
            printf "%s\n" "$line" >> "$tmpfile"
        done
        echo "" >> "$tmpfile"
    fi

    #################
    # Process Files
    #################
    files=()
    while IFS= read -r -d '' file; do
        fbase=$(basename "$file")
        if [ -n "$fbase" ]; then
            files+=( "$fbase" )
        fi
    done < <(find "$dir" -mindepth 1 -maxdepth 1 -type f ! -path "$readme" -print0)
    
    if [ ${#files[@]} -gt 0 ]; then
        # Sort file names alphabetically.
        mapfile -t sorted_files < <(printf "%s\n" "${files[@]}" | sort)
        echo "## Files" >> "$tmpfile"
        for f in "${sorted_files[@]}"; do
            line="- [[${f}]]"
            printf "%s\n" "$line" >> "$tmpfile"
        done
        echo "" >> "$tmpfile"
    fi

    # If the README already exists, compare its body (from line 3 onward)
    # with the new content (ignoring the first two lines, which contain the date header).
    if [ -f "$readme" ]; then
        if diff -q <(tail -n +3 "$tmpfile") <(tail -n +3 "$readme") >/dev/null; then
            rm "$tmpfile"
            echo "[$count/$total] No change: $dir"
            continue
        fi
    fi

    # Update (or create) the README.
    mv "$tmpfile" "$readme"
    echo "[$count/$total] Updated: $dir"
done

