#!/usr/bin/env bash

#############################################################################
# Bash Documentation Generator with Animated GIFs
#
# Generate sexy, comprehensive README.md files with embedded asciinema GIFs
# for any POSIX-compliant executables (those with --help)
#
# Usage:
#   doc_bash_generate.sh [OPTIONS] <executable> [executable...]
#   doc_bash_generate.sh [OPTIONS] "*.sh"
#
# Arguments:
#   executable          One or more executables or glob patterns
#
# Options:
#   -o, --output FILE   Output README.md path (default: ./README.md)
#   -t, --title TITLE   Documentation title (default: auto-generated)
#   --no-gif            Skip GIF generation (faster, text only)
#   --gif-only          Only generate GIFs, don't update README
#   -h, --help          Show this help message
#
# Examples:
#   doc_bash_generate.sh css_*.sh
#   doc_bash_generate.sh -o docs/README.md *.sh
#   doc_bash_generate.sh --title "My Awesome Tools" script1.sh script2.sh
#
# Dependencies:
#   asciinema           For terminal recording
#   agg                 For converting asciinema to GIF (cargo install agg)
#
#############################################################################

set -euo pipefail

# ============================================================================
# Color Definitions
# ============================================================================

RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" BOLD="" DIM="" RESET=""
COLORS=0

if [[ -t 1 ]] && command -v tput >/dev/null 2>&1; then
    COLORS=$(tput colors 2>/dev/null || echo 0)
    if [[ ${COLORS:-0} -ge 8 ]]; then
        RED=$(tput setaf 1 2>/dev/null || echo "")
        GREEN=$(tput setaf 2 2>/dev/null || echo "")
        YELLOW=$(tput setaf 3 2>/dev/null || echo "")
        BLUE=$(tput setaf 4 2>/dev/null || echo "")
        MAGENTA=$(tput setaf 5 2>/dev/null || echo "")
        CYAN=$(tput setaf 6 2>/dev/null || echo "")
        BOLD=$(tput bold 2>/dev/null || echo "")
        DIM=$(tput dim 2>/dev/null || echo "")
        RESET=$(tput sgr0 2>/dev/null || echo "")
    fi
fi

# ============================================================================
# Configuration
# ============================================================================

OUTPUT_FILE="$PWD/README.md"
DOC_TITLE=""
SKIP_GIF=false
GIF_ONLY=false
declare -a EXECUTABLES=()
TEMP_DIR=""

# ============================================================================
# Helper Functions
# ============================================================================

print_usage() {
    cat << EOF
${BOLD}Bash Documentation Generator with Animated GIFs${RESET}

Generate sexy, comprehensive README.md files with embedded asciinema GIFs.

${BOLD}USAGE:${RESET}
    $(basename "$0") [OPTIONS] <executable> [executable...]

${BOLD}ARGUMENTS:${RESET}
    executable          One or more executables or glob patterns

${BOLD}OPTIONS:${RESET}
    -o, --output FILE   Output README.md path (default: ./README.md)
    -t, --title TITLE   Documentation title (default: auto-generated)
    --no-gif            Skip GIF generation (faster, text only)
    --gif-only          Only generate GIFs, don't update README
    -h, --help          Show this help message

${BOLD}EXAMPLES:${RESET}
    $(basename "$0") css_*.sh
    $(basename "$0") -o docs/README.md *.sh
    $(basename "$0") --title "My Awesome Tools" script1.sh script2.sh

${BOLD}DEPENDENCIES:${RESET}
    asciinema           Terminal session recorder
    agg                 Asciinema to GIF converter (cargo install agg)

${BOLD}NOTES:${RESET}
    Demos are automatically generated by running ${DIM}--help${RESET} on each command.
    GIF recordings are created in a temporary directory and cleaned up after.

EOF
}

error() {
    echo "${RED}${BOLD}Error:${RESET} $1" >&2
    exit 1
}

info() {
    echo "${BLUE}${BOLD}==>${RESET} $1" >&2
}

success() {
    echo "${GREEN}${BOLD}[OK]${RESET} $1" >&2
}

warning() {
    echo "${YELLOW}${BOLD}[WARN]${RESET} $1" >&2
}

banner() {
    echo "" >&2
    echo "${BOLD}${MAGENTA}================================================================${RESET}" >&2
    echo "${BOLD}${MAGENTA}  $1${RESET}" >&2
    echo "${BOLD}${MAGENTA}================================================================${RESET}" >&2
    echo "" >&2
}

cleanup() {
    if [[ -n "${TEMP_DIR:-}" ]] && [[ -d "$TEMP_DIR" ]]; then
        rm -rf "$TEMP_DIR"
    fi
}

trap cleanup EXIT

check_dependencies() {
    local missing=()

    if ! command -v asciinema >/dev/null 2>&1; then
        missing+=("asciinema")
    fi

    if ! command -v agg >/dev/null 2>&1 && [[ "$SKIP_GIF" == "false" ]]; then
        warning "agg not found. Install with: cargo install agg"
        warning "Continuing without GIF generation..."
        SKIP_GIF=true
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        error "Missing required dependencies: ${missing[*]}"
    fi
}

# ============================================================================
# Help Parsing Functions
# ============================================================================

get_command_help() {
    local cmd="$1"

    if [[ ! -x "$cmd" ]]; then
        warning "Command not executable: $cmd"
        return 1
    fi

    # Try --help, then -h, then fail
    local help_output
    if help_output=$("$cmd" --help 2>&1); then
        echo "$help_output"
        return 0
    elif help_output=$("$cmd" -h 2>&1); then
        echo "$help_output"
        return 0
    else
        warning "Command doesn't support --help: $cmd"
        return 1
    fi
}

extract_description() {
    local help_text="$1"

    # Try to find first non-empty line after header/title
    echo "$help_text" | grep -v "^#" | grep -v "^-" | grep -v "^=" | \
        grep -E "^[A-Z]" | head -n 1 | sed 's/^[[:space:]]*//'
}

extract_usage() {
    local help_text="$1"

    # Find USAGE section
    echo "$help_text" | sed -n '/USAGE:/,/^$/p' | grep -v "USAGE:" | \
        sed 's/^[[:space:]]*//'
}

extract_examples() {
    local help_text="$1"

    # Find EXAMPLES section
    echo "$help_text" | sed -n '/EXAMPLES:/,/^[A-Z]/p' | grep -v "EXAMPLES:" | \
        grep -v "^[A-Z]" | sed 's/^[[:space:]]*//'
}

# ============================================================================
# Asciinema Recording Functions
# ============================================================================

extract_example_commands() {
    local help_text="$1"
    local cmd_name="$2"

    # Extract example commands from EXAMPLES section
    # Look for lines that start with the command name or common patterns
    echo "$help_text" | sed -n '/EXAMPLES:/,/^[A-Z]/p' | \
        grep -E "^\s*($cmd_name|#|$)" | \
        grep -v "^#" | \
        grep -v "EXAMPLES:" | \
        grep -v "^[A-Z]" | \
        sed 's/^[[:space:]]*//' | \
        grep -v "^$" | \
        head -n 2
}

create_demo() {
    local cmd="$1"
    local cmd_name=$(basename "$cmd")

    # Create demo file in temp directory
    local demo_file="$TEMP_DIR/${cmd_name%.sh}.demo"

    # Get help text to extract examples
    local help_text=$("$cmd" --help 2>&1 || true)

    # Extract example commands from EXAMPLES section
    local examples=$(echo "$help_text" | sed -n '/EXAMPLES:/,/^[A-Z]/p' | \
        grep -E "^\s*$cmd_name" | head -n 2 | sed 's/^[[:space:]]*//')

    cat > "$demo_file" << 'DEMO_HEADER'
#!/usr/bin/env bash
# Auto-generated demo

echo ""
echo "=== Demo: $CMD_NAME ==="
echo ""
DEMO_HEADER

    # If we have examples, run them
    if [[ -n "$examples" ]]; then
        echo '# Show examples' >> "$demo_file"
        echo 'echo ""' >> "$demo_file"

        while IFS= read -r example; do
            if [[ -n "$example" ]]; then
                # Show the command being run
                echo "echo '$ $example'" >> "$demo_file"
                echo 'echo ""' >> "$demo_file"

                # Run the command with timeout (15 seconds max)
                # Replace the script name with full path
                local full_example="${example/$cmd_name/$cmd}"
                cat >> "$demo_file" << EOF
timeout 15s $full_example 2>&1 || {
    exit_code=\$?
    if [ \$exit_code -eq 124 ]; then
        echo "[Example timed out after 15s - computation too intensive for demo]"
    else
        echo "[Command requires additional setup or arguments]"
    fi
}
EOF
                echo 'echo ""' >> "$demo_file"
            fi
        done <<< "$examples"
    else
        # Fallback to showing help if no examples found
        echo 'echo "$ $CMD_NAME --help | head -n 20"' >> "$demo_file"
        echo 'echo ""' >> "$demo_file"
        echo "$cmd --help 2>&1 | head -n 20" >> "$demo_file"
    fi

    echo 'echo ""' >> "$demo_file"

    # Replace placeholder with actual command name
    sed -i "s|\$CMD_NAME|$cmd_name|g" "$demo_file"

    chmod +x "$demo_file"
    echo "$demo_file"
}

record_demo() {
    local cmd="$1"
    local output_cast="$2"
    local demo_script="$3"

    info "Recording demo for $(basename "$cmd")..."

    # Create a sandbox directory for demo execution
    local sandbox_dir="$TEMP_DIR/sandbox"
    mkdir -p "$sandbox_dir"

    # Create a wrapper script that runs the demo in sandbox
    local wrapper="$TEMP_DIR/demo_wrapper.sh"
    cat > "$wrapper" << 'WRAPPER_EOF'
#!/usr/bin/env bash
set -e

# Set terminal size for consistent output
export COLUMNS=100
export LINES=30

# Change to sandbox directory for safe execution
cd "$3"

# Add some style
echo -e "\033[1;36m"
echo "========================================"
echo "  Demo: $(basename "$1")"
echo "========================================"
echo -e "\033[0m"
echo ""
sleep 1

# Source the demo script
source "$2"

echo ""
sleep 2
WRAPPER_EOF

    chmod +x "$wrapper"

    # Record with asciinema (redirect all output to avoid contamination)
    asciinema rec \
        --command "$wrapper '$cmd' '$demo_script' '$sandbox_dir'" \
        --overwrite \
        --cols 100 \
        --rows 30 \
        "$output_cast" >/dev/null 2>&1

    if [[ $? -eq 0 ]]; then
        success "Recorded: $output_cast"
        return 0
    else
        warning "Failed to record demo for $(basename "$cmd")"
        return 1
    fi
}

convert_to_gif() {
    local cast_file="$1"
    local gif_file="$2"

    info "Converting to GIF: $(basename "$gif_file")..."

    if command -v agg >/dev/null 2>&1; then
        agg \
            --font-size 14 \
            --speed 1.5 \
            --theme monokai \
            "$cast_file" \
            "$gif_file" >/dev/null 2>&1

        if [[ $? -eq 0 ]]; then
            success "Created GIF: $(basename "$gif_file")"
            return 0
        fi
    fi

    warning "Failed to convert to GIF: $(basename "$cast_file")"
    return 1
}

# ============================================================================
# README Generation Functions
# ============================================================================

generate_readme_header() {
    local title="$1"
    local output_dir=$(dirname "$OUTPUT_FILE")

    cat << EOF
# $title

> Comprehensive documentation with usage examples and demos

This documentation was auto-generated using [\`doc_bash_generate.sh\`](https://github.com/yourusername/yourrepo).

## Table of Contents

EOF
}

generate_toc_entry() {
    local cmd="$1"
    local cmd_name=$(basename "$cmd")
    local slug=$(echo "$cmd_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g')

    echo "- [\`$cmd_name\`](#$slug)"
}

generate_command_section() {
    local cmd="$1"
    local gif_path="$2"
    local help_text="$3"
    local cmd_name=$(basename "$cmd")

    cat << EOF

---

## \`$cmd_name\`

EOF

    # Add description
    local description=$(extract_description "$help_text")
    if [[ -n "$description" ]]; then
        echo "$description"
        echo ""
    fi

    # Add GIF if exists
    if [[ -f "$gif_path" ]]; then
        local gif_rel_path="docs/img/$(basename "$gif_path")"
        cat << EOF
### Demo

![Demo of $cmd_name]($gif_rel_path)

EOF
    fi

    # Add usage section
    cat << EOF
### Usage

\`\`\`bash
$cmd_name [OPTIONS] [ARGUMENTS]
\`\`\`

EOF

    # Add full help output
    cat << EOF
### Options

<details>
<summary>Click to expand full help output</summary>

\`\`\`
$help_text
\`\`\`

</details>

EOF

    # Add examples if available
    local examples=$(extract_examples "$help_text")
    if [[ -n "$examples" ]]; then
        cat << EOF
### Examples

\`\`\`bash
$examples
\`\`\`

EOF
    fi
}

generate_readme_footer() {
    cat << EOF

---

## Installation

All scripts are available in this repository. Make sure they are executable:

\`\`\`bash
chmod +x *.sh
\`\`\`

Add them to your PATH for easy access:

\`\`\`bash
export PATH="\$PATH:\$(pwd)"
\`\`\`

## Dependencies

Common dependencies for these scripts:
- \`bash\` (4.0+)
- \`bc\` - For floating-point arithmetic

Specific dependencies are listed in each command's help output.

## Contributing

Contributions are welcome! Please ensure:
- Scripts follow POSIX conventions
- Include comprehensive \`--help\` output with usage examples

## License

MIT License - See LICENSE file for details.

---

*Documentation generated on $(date '+%Y-%m-%d %H:%M:%S %Z') by [\`doc_bash_generate.sh\`](https://github.com/yourusername/yourrepo)*

EOF
}

# ============================================================================
# Main Processing Functions
# ============================================================================

process_command() {
    local cmd="$1"
    local cmd_name=$(basename "$cmd")
    local output_dir=$(dirname "$OUTPUT_FILE")
    local img_dir="$output_dir/docs/img"

    info "Processing: ${BOLD}$cmd_name${RESET}"

    # Create image directory
    mkdir -p "$img_dir"

    # Get help text
    local help_text
    if ! help_text=$(get_command_help "$cmd" 2>&1); then
        warning "Skipping $cmd_name - no help available"
        return 1
    fi

    # Setup paths
    local cast_file="$TEMP_DIR/${cmd_name%.sh}.cast"
    local gif_file="$img_dir/${cmd_name%.sh}.gif"

    # Handle GIF generation
    if [[ "$SKIP_GIF" == "false" ]]; then
        # Create demo script in temp directory
        local demo_script=$(create_demo "$cmd")

        # Record and convert
        if record_demo "$cmd" "$cast_file" "$demo_script"; then
            convert_to_gif "$cast_file" "$gif_file" || true
        fi
    fi

    # Return data for README generation (base64 encode help text to preserve newlines)
    local encoded_help=$(echo "$help_text" | base64 -w 0)
    echo "$cmd|$gif_file|$encoded_help"
}

build_readme() {
    local -a command_data=("$@")

    info "Building README.md..."

    local title="${DOC_TITLE:-"Script Documentation"}"
    local readme_content=""

    # Generate header
    readme_content+=$(generate_readme_header "$title")
    readme_content+=$'\n'

    # Generate TOC
    for data in "${command_data[@]}"; do
        # Split data using bash parameter expansion to avoid IFS issues
        local cmd="${data%%|*}"
        local rest="${data#*|}"
        local gif_path="${rest%%|*}"
        local encoded_help="${rest#*|}"

        readme_content+=$(generate_toc_entry "$cmd")
        readme_content+=$'\n'
    done

    readme_content+=$'\n'

    # Generate command sections
    for data in "${command_data[@]}"; do
        # Split data using bash parameter expansion to avoid IFS issues
        local cmd="${data%%|*}"
        local rest="${data#*|}"
        local gif_path="${rest%%|*}"
        local encoded_help="${rest#*|}"
        local help_text=$(echo "$encoded_help" | base64 -d 2>/dev/null || echo "")

        readme_content+=$(generate_command_section "$cmd" "$gif_path" "$help_text")
        readme_content+=$'\n'
    done

    # Generate footer
    readme_content+=$(generate_readme_footer)

    # Write to file
    echo "$readme_content" > "$OUTPUT_FILE"

    success "README generated: $OUTPUT_FILE"
}

# ============================================================================
# Argument Parsing
# ============================================================================

parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -h|--help)
                print_usage
                exit 0
                ;;
            -o|--output)
                OUTPUT_FILE="$2"
                shift 2
                ;;
            -t|--title)
                DOC_TITLE="$2"
                shift 2
                ;;
            --no-gif)
                SKIP_GIF=true
                shift
                ;;
            --gif-only)
                GIF_ONLY=true
                shift
                ;;
            -*)
                error "Unknown option: $1"
                ;;
            *)
                # Handle glob patterns
                if [[ "$1" == *"*"* ]] || [[ "$1" == *"?"* ]]; then
                    # Expand glob
                    for file in $1; do
                        if [[ -f "$file" ]]; then
                            EXECUTABLES+=("$file")
                        fi
                    done
                else
                    if [[ -f "$1" ]]; then
                        EXECUTABLES+=("$1")
                    else
                        warning "File not found: $1"
                    fi
                fi
                shift
                ;;
        esac
    done

    if [[ ${#EXECUTABLES[@]} -eq 0 ]]; then
        error "No executables specified. Use --help for usage information."
    fi
}

# ============================================================================
# Main Script Logic
# ============================================================================

main() {
    banner "Bash Documentation Generator"

    parse_arguments "$@"
    check_dependencies

    # Create temp directory
    TEMP_DIR=$(mktemp -d)

    info "Output: $OUTPUT_FILE"
    info "Commands: ${#EXECUTABLES[@]}"
    echo ""

    # Process all commands
    local -a command_data=()
    for cmd in "${EXECUTABLES[@]}"; do
        local result
        if result=$(process_command "$cmd"); then
            command_data+=("$result")
        fi
        echo ""
    done

    if [[ ${#command_data[@]} -eq 0 ]]; then
        error "No commands were successfully processed"
    fi

    # Build README unless gif-only mode
    if [[ "$GIF_ONLY" == "false" ]]; then
        build_readme "${command_data[@]}"
    fi

    echo ""
    banner "Documentation Complete!"

    echo "${BOLD}Generated Files:${RESET}"
    if [[ "$GIF_ONLY" == "false" ]]; then
        echo "  ${GREEN}*${RESET} $OUTPUT_FILE"
    fi
    if [[ "$SKIP_GIF" == "false" ]]; then
        local img_dir="$(dirname "$OUTPUT_FILE")/docs/img"
        if [[ -d "$img_dir" ]]; then
            local gif_count=$(find "$img_dir" -name "*.gif" 2>/dev/null | wc -l)
            echo "  ${GREEN}*${RESET} $gif_count GIF(s) in $img_dir"
        fi
    fi
    echo ""

    success "All done! Check out your sexy new documentation!"
}

main "$@"
