#!/usr/bin/env bash
# ─── Repository analysis via AI agent ────────────────────────────────────────

# The bootstrap prompt injected at the top of ai/index.md.
# Used for manual agent sessions (not for kronn automated analysis).
BOOTSTRAP_MARKER_START="<!-- KRONN:BOOTSTRAP:START -->"
BOOTSTRAP_MARKER_END="<!-- KRONN:BOOTSTRAP:END -->"

# Inject the bootstrap prompt into ai/index.md if not already present.
inject_bootstrap_prompt() {
    local repo_dir="$1"
    local index_file="$repo_dir/ai/index.md"

    [[ -f "$index_file" ]] || return 1

    # Already has bootstrap prompt?
    if grep -q "$BOOTSTRAP_MARKER_START" "$index_file" 2>/dev/null; then
        return 0
    fi

    local prompt
    prompt=$(cat <<'PROMPT'
<!-- KRONN:BOOTSTRAP:START -->
<!-- ================================================================
     BOOTSTRAP INSTRUCTIONS — AUTO-GENERATED BY KRONN
     ================================================================
     This block is for AI agents only. It instructs you to analyze
     this repository and fill in the ai/ documentation skeleton.

     After completing the analysis, you MUST delete this entire block
     (from KRONN:BOOTSTRAP:START to KRONN:BOOTSTRAP:END).
     ================================================================ -->

> **FIRST-RUN TASK — Bootstrap ai/ documentation**
>
> This is a fresh `ai/` skeleton. You must analyze the repository and fill in all files.
>
> **Rules:**
> - All `ai/` files MUST be in **English**
> - Content is **AI context** (factual, concise), NOT human documentation
> - Do NOT invent information — mark unknowns with `<!-- TODO: verify with team -->`
>
> **Procedure:**
>
> 1. **Analyze the project** — Read README.md, package.json, composer.json, Cargo.toml,
>    Makefile, Dockerfile, docker-compose.yml, CI configs, main config files.
>    Determine: stack, structure, build/dev commands, key patterns, third parties, testing, CI/CD.
>
> 2. **Fill `ai/index.md`** — Replace all `{{PLACEHOLDERS}}` and `<!-- comments -->`:
>    project name, stack summary, common tasks table, prerequisites, DO NOT rules,
>    workflow constraints, source of truth, code placement, stack facts, date.
>
> 3. **Fill `ai/repo-map.md`** — Map key folders, config files, entry points.
>
> 4. **Fill `ai/glossary.md`** — Extract domain terms, abbreviations, internal names.
>
> 5. **Fill `ai/coding-rules.md`** — Linters, formatters, naming conventions.
>
> 6. **Fill `ai/testing-quality.md`** — Test frameworks, commands, quality gates.
>
> 7. **Fill `ai/architecture/overview.md`** — Services, patterns, separation of concerns.
>
> 8. **Fill `ai/operations/mcp-servers.md`** — Document configured MCP servers if any.
>
> 9. **Fill `ai/operations/debug-operations.md`** — Common commands, troubleshooting.
>
> 10. **Fill `ai/inconsistencies-tech-debt.md`** — Note any inconsistencies, legacy
>     patterns, or tech debt discovered during analysis.
>
> 11. **Review** — Ensure no `{{PLACEHOLDER}}` remains. Remove filled `<!-- comments -->`.
>     Keep `<!-- TODO -->` for items needing human verification.
>
> 12. **DELETE THIS ENTIRE BLOCK** (from `KRONN:BOOTSTRAP:START` to `KRONN:BOOTSTRAP:END`).
>
> When done, summarize: files filled, items needing human input, suggested deep-dives.

<!-- KRONN:BOOTSTRAP:END -->

PROMPT
)

    # Prepend bootstrap prompt to index.md
    # Create temp in same directory to avoid cross-filesystem mv failures
    local tmp
    tmp=$(mktemp "$repo_dir/ai/.index.md.XXXXXX") || {
        echo "ERROR: Failed to create temp file in $repo_dir/ai/" >&2
        return 1
    }
    {
        echo "$prompt"
        cat "$index_file"
    } > "$tmp" || {
        rm -f "$tmp"
        echo "ERROR: Failed to write to $tmp" >&2
        return 1
    }
    mv "$tmp" "$index_file" || {
        rm -f "$tmp"
        echo "ERROR: Failed to replace $index_file" >&2
        return 1
    }
}

# Check if bootstrap prompt is still present (not yet analyzed).
has_bootstrap_prompt() {
    local repo_dir="$1"
    grep -q "$BOOTSTRAP_MARKER_START" "$repo_dir/ai/index.md" 2>/dev/null
}

# Remove bootstrap prompt from ai/index.md.
remove_bootstrap_prompt() {
    local repo_dir="$1"
    local index_file="$repo_dir/ai/index.md"
    [[ -f "$index_file" ]] || return 0
    # GNU sed (Linux), BusyBox sed (Alpine), BSD sed (macOS) all differ on -i
    # Safest cross-platform approach: use -i.bak then cleanup
    if sed --version 2>&1 | grep -q "GNU"; then
        # GNU sed (Ubuntu, Fedora, Arch)
        sed -i "\|$BOOTSTRAP_MARKER_START|,\|$BOOTSTRAP_MARKER_END|d" "$index_file"
    else
        # BSD sed (macOS) or BusyBox sed (Alpine): use backup extension
        sed -i.kronn-bak "\|$BOOTSTRAP_MARKER_START|,\|$BOOTSTRAP_MARKER_END|d" "$index_file"
        rm -f "$index_file.kronn-bak"
    fi
}

# ─── Prompts ─────────────────────────────────────────────────────────────────

# Common preamble injected into every agent prompt.
_PROMPT_PREAMBLE="Rules: Write in English. Be factual and concise — this is AI context for agents, not human documentation. Do NOT invent information — mark unknowns with <!-- TODO: verify -->. Replace all {{PLACEHOLDERS}} and <!-- fill --> comments with real content. Keep the existing file structure and headings."

# Analysis steps: file|prompt
# Each step = one `claude -p` call = 10% progress
_ANALYSIS_STEPS=(
    "ai/index.md|Analyze this repository. Read README.md, package.json or composer.json or Cargo.toml, Makefile, Dockerfile, docker-compose.yml, CI configs (.github/workflows, .gitlab-ci.yml), and main config files. Determine the stack, project structure, build/dev commands, key patterns, third-party services, testing setup, and CI/CD pipeline. Then fill ai/index.md: replace the project name, stack summary, common tasks table, prerequisites, DO NOT rules, workflow constraints, source of truth, code placement rules, and stack facts. Set the date to today."
    "ai/repo-map.md|Read ai/index.md for project context. Explore the directory structure of this repository. Fill ai/repo-map.md: list key folders and what they contain, primary config files, and entry points."
    "ai/coding-rules.md|Read ai/index.md for project context. Find all linter, formatter, and type-checker configs in the repo (e.g. .eslintrc, prettier, phpcs, rustfmt, tsconfig, etc). Fill ai/coding-rules.md with the actual tools, their config file paths, and run commands."
    "ai/testing-quality.md|Read ai/index.md for project context. Find test framework configs (jest, phpunit, pytest, vitest, etc) and CI quality gates. Fill ai/testing-quality.md with test commands, config file locations, and quality gates."
    "ai/architecture/overview.md|Read ai/index.md for project context. Analyze the high-level architecture: services/apps, key design patterns, separation of concerns, and any legacy aspects. Fill ai/architecture/overview.md."
    "ai/glossary.md|Read ai/index.md for project context. Search the codebase for domain-specific terms, abbreviations, internal naming conventions, and project jargon. Fill ai/glossary.md organized by category (architecture, business domain, third parties, etc)."
    "ai/operations/debug-operations.md|Read ai/index.md for project context. Find operational commands from Makefile, package.json scripts, docker-compose commands, and any run/build/debug procedures. Fill ai/operations/debug-operations.md with common commands and troubleshooting steps."
    "ai/operations/mcp-servers.md|Read ai/index.md for project context. Check if .mcp.json or .mcp.json.example exists in the repo. If yes, document the configured MCP servers in ai/operations/mcp-servers.md. If no MCP config exists, replace the file content with: '# MCP Servers\n\nNo MCP servers configured for this project.'"
    "ai/inconsistencies-tech-debt.md|Read ai/index.md and browse the other ai/ files you filled in previous steps. Based on everything you observed during analysis, note any inconsistencies, legacy patterns, outdated configs, or technical debt. Fill ai/inconsistencies-tech-debt.md with concrete, factual entries."
    "REVIEW|Read ALL ai/ files. Check for: remaining {{PLACEHOLDERS}}, unfilled <!-- comments -->, inconsistencies between files, duplicate information. Fix any issues found. Remove any remaining <!-- fill --> comments. Ensure all files are coherent with each other. This is the final quality pass — make the documentation clean and useful."
)

# ─── Agent execution ─────────────────────────────────────────────────────────

# Run a single analysis step via the agent.
# Args: agent, prompt, repo_dir, activity_file
_run_analysis_step() {
    local agent="$1" prompt="$2" repo_dir="$3" activity_file="$4"
    local full_prompt="${_PROMPT_PREAMBLE} ${prompt}"

    case "$agent" in
        claude)
            (cd "$repo_dir" && claude -p --permission-mode acceptEdits "$full_prompt" > /dev/null 2>&1)
            ;;
        codex)
            (cd "$repo_dir" && codex "$full_prompt" > /dev/null 2>&1)
            ;;
        vibe)
            (cd "$repo_dir" && vibe -p "$full_prompt" > /dev/null 2>&1)
            ;;
        copilot)
            (cd "$repo_dir" && copilot -p "$full_prompt" > /dev/null 2>&1)
            ;;
    esac
}

# ─── Agent analysis ──────────────────────────────────────────────────────────

# Run the selected agent to analyze a repo and fill ai/ docs.
# Uses sequential per-file calls for real progress tracking.
analyze_repo() {
    local repo_dir="$1"
    local agent="${SELECTED_AGENT:-claude}"
    local repo_name
    repo_name=$(basename "$repo_dir")

    step "Analysis of $repo_name by $agent"

    # Verify agent is installed and supports non-interactive mode
    case "$agent" in
        claude|codex|vibe|copilot)
            if ! command -v "$agent" >/dev/null 2>&1; then
                fail "$agent is not installed or not in PATH."
                return 1
            fi
            ;;
        *)
            fail "Agent $agent: auto-analysis not available."
            info "Launch your agent manually in the repository."
            return 0
            ;;
    esac

    # Remove bootstrap prompt if present (we use our own per-step prompts)
    remove_bootstrap_prompt "$repo_dir"

    # Prepare loader
    tron_init "$repo_dir"

    local activity_file
    activity_file=$(mktemp "${TMPDIR:-/tmp}/kronn-activity-XXXXXX")
    tron_set_log "$activity_file"
    tron_set_agent "$agent"

    local total_steps=${#_ANALYSIS_STEPS[@]}

    # Background: run steps sequentially, update progress
    (
        local step_num=0

        for step_entry in "${_ANALYSIS_STEPS[@]}"; do
            local target_file="${step_entry%%|*}"
            local step_prompt="${step_entry#*|}"

            step_num=$((step_num + 1))
            local pct=$((step_num * 100 / total_steps))

            # Update step label and progress
            if [[ "$target_file" == "REVIEW" ]]; then
                tron_set_step "Review and finalization"
            else
                tron_set_step "$target_file"
            fi
            tron_progress "$pct"

            # Log activity
            if [[ "$target_file" == "REVIEW" ]]; then
                echo "Global review..." > "$activity_file"
            else
                echo "✎ $(basename "$target_file")" >> "$activity_file"
            fi

            # Run the agent for this step
            _run_analysis_step "$agent" "$step_prompt" "$repo_dir" "$activity_file"
            local exit_code=$?

            if [[ $exit_code -ne 0 ]]; then
                echo "ERROR: $target_file (code $exit_code)" >> "$activity_file"
            fi
        done

        tron_progress 100
        sleep 0.5
        tron_signal_done
    ) &
    local bg_pid=$!

    # Run the loader (blocking until signal_done)
    tron_loader_run "Analysis of $repo_name"

    # Collect exit code
    wait "$bg_pid" 2>/dev/null
    local exit_code=$?

    tron_cleanup

    if [[ $exit_code -eq 0 ]]; then
        echo
        success "Analysis complete — $total_steps steps completed."
    else
        echo
        fail "Error during analysis."
    fi

    rm -f "$activity_file" 2>/dev/null || true
}

# ─── Interactive analysis prompt ─────────────────────────────────────────────

# Ask user if they want to run agent analysis on a repo.
maybe_analyze_repo() {
    local repo_dir="$1"

    # Only propose if ai/ files still have placeholders
    if ! grep -rq '{{' "$repo_dir/ai/" 2>/dev/null; then
        return 0
    fi

    echo
    local agent_label="${SELECTED_AGENT:-agent}"
    if ask_yn "Analyze the repository with $agent_label to structure ai/?"; then
        analyze_repo "$repo_dir"
    else
        info "Run 'kronn init $repo_dir' when you are ready."
    fi
}
