"""Detect undo/revert requests, AI self-correction, AI clarification questions, git operations.

Key findings:
- Genuine undo/revert requests: ~46 (must strip gemini file refs to avoid false positives)
- AI apology/self-correction: 443 instances
- AI clarification questions: 660 instances (but many are "let me know" sign-offs, not real questions)
- Git operations: commit=677, push=414, diff=417, checkout=104, reset=26

Run: /home/sagar/trace/.venv/bin/python3 analysis-14022026/session_view_scripts/research/04_undo_revert_and_ai_behavior.py
"""
import json
import os

DIR = os.path.join(os.path.dirname(__file__), "../viewer/public/data/sessions")
IDX = os.path.join(os.path.dirname(__file__), "../viewer/public/data/index.json")

GEMINI_REF = "--- Content from referenced files ---"

with open(IDX) as f:
    index = json.load(f)


def strip_gemini_refs(content: str) -> str:
    """Return only the human-written part of a message."""
    if GEMINI_REF in content:
        return content[: content.index(GEMINI_REF)].strip()
    return content


# ---- Part 1: Undo/revert detection ----
print("=" * 60)
print("PART 1: User undo/revert requests")
print("=" * 60)

undo_keywords = [
    "undo",
    "revert this",
    "revert that",
    "revert the",
    "roll back",
    "go back to",
    "put it back",
    "restore the",
]

undo_count = 0
undo_examples = []

for dev in index["developers"].values():
    for s in dev["sessions"]:
        fpath = os.path.join(DIR, f'{s["id"]}.json')
        if not os.path.exists(fpath):
            continue
        with open(fpath) as f2:
            msgs = json.load(f2)
        for m in msgs:
            if m["type"] != "user" or not m.get("content"):
                continue
            c = strip_gemini_refs(m["content"])
            c_lower = c.lower().strip()
            if len(c_lower) < 5:
                continue
            # Skip compaction summaries
            if c_lower.startswith("this session is being continued"):
                continue
            for kw in undo_keywords:
                if kw in c_lower:
                    undo_count += 1
                    if len(undo_examples) < 10:
                        undo_examples.append((s["source"], c.strip()[:200]))
                    break

print(f"Genuine undo/revert requests: {undo_count}")
for src, ex in undo_examples:
    print(f"  [{src}] {repr(ex)}")

# ---- Part 2: AI self-correction patterns ----
print("\n" + "=" * 60)
print("PART 2: AI self-correction (apologies)")
print("=" * 60)

ai_apology_patterns = [
    "I apologize",
    "my mistake",
    "let me fix that",
    "that was incorrect",
    "sorry about",
    "I made an error",
    "that's wrong",
]
ai_apology_count = 0
ai_apology_examples = []

for dev in index["developers"].values():
    for s in dev["sessions"]:
        fpath = os.path.join(DIR, f'{s["id"]}.json')
        if not os.path.exists(fpath):
            continue
        with open(fpath) as f2:
            msgs = json.load(f2)
        for m in msgs:
            if m["type"] != "assistant" or not m.get("content"):
                continue
            c = m["content"]
            for pat in ai_apology_patterns:
                if pat.lower() in c.lower():
                    ai_apology_count += 1
                    if len(ai_apology_examples) < 5:
                        ai_apology_examples.append(c[:200])
                    break

print(f"AI self-correction/apology count: {ai_apology_count}")
for ex in ai_apology_examples:
    print(f"  {repr(ex)}")

# ---- Part 3: AI clarification questions ----
print("\n" + "=" * 60)
print("PART 3: AI clarification questions")
print("=" * 60)

# These are REAL questions, not "let me know" sign-offs
real_clarification = [
    "would you like me to",
    "do you want me to",
    "should I ",
    "could you clarify",
    "which one ",
    "before I proceed",
    "would you prefer",
    "do you want to",
]
# These are sign-offs that aren't real questions
signoff_patterns = ["let me know", "feel free to", "if you have any"]

ai_question_count = 0
ai_signoff_count = 0
ai_question_examples = []

for dev in index["developers"].values():
    for s in dev["sessions"]:
        fpath = os.path.join(DIR, f'{s["id"]}.json')
        if not os.path.exists(fpath):
            continue
        with open(fpath) as f2:
            msgs = json.load(f2)
        for m in msgs:
            if m["type"] != "assistant" or not m.get("content"):
                continue
            c_lower = m["content"].lower()

            is_real_q = any(pat in c_lower for pat in real_clarification)
            is_signoff = any(pat in c_lower for pat in signoff_patterns)

            if is_real_q and not is_signoff:
                ai_question_count += 1
                if len(ai_question_examples) < 5:
                    ai_question_examples.append(m["content"][:200])
            elif is_signoff:
                ai_signoff_count += 1

print(f"Real AI clarification questions: {ai_question_count}")
print(f"AI sign-off (not real questions): {ai_signoff_count}")
for ex in ai_question_examples:
    print(f"  {repr(ex)}")

# ---- Part 4: Git operations in bash tool calls ----
print("\n" + "=" * 60)
print("PART 4: Git operations in shell tool calls")
print("=" * 60)

git_patterns = {
    "git commit": 0,
    "git push": 0,
    "git diff": 0,
    "git checkout": 0,
    "git reset": 0,
    "git restore": 0,
    "git stash": 0,
    "git revert": 0,
    "git merge": 0,
    "git pull": 0,
}

shell_tools = {"Bash", "shell_command", "exec_command", "run_shell_command", "run_terminal_cmd"}

for dev in index["developers"].values():
    for s in dev["sessions"]:
        fpath = os.path.join(DIR, f'{s["id"]}.json')
        if not os.path.exists(fpath):
            continue
        with open(fpath) as f2:
            msgs = json.load(f2)
        for m in msgs:
            if m["type"] == "tool_call" and m.get("tool", {}).get("tool_name") in shell_tools:
                ti = m["tool"].get("tool_input", "").lower()
                for gp in git_patterns:
                    if gp in ti:
                        git_patterns[gp] += 1

print(f"Git operations: {git_patterns}")

# ---- Part 5: Session ending patterns ----
print("\n" + "=" * 60)
print("PART 5: How do sessions end?")
print("=" * 60)

endings = {"user": 0, "assistant": 0, "tool_call": 0, "tool_result": 0, "other": 0}
total = 0

for dev in index["developers"].values():
    for s in dev["sessions"]:
        fpath = os.path.join(DIR, f'{s["id"]}.json')
        if not os.path.exists(fpath):
            continue
        with open(fpath) as f2:
            msgs = json.load(f2)
        if not msgs:
            continue
        total += 1
        last_type = msgs[-1]["type"]
        if last_type in endings:
            endings[last_type] += 1
        else:
            endings["other"] += 1

print(f"Session endings (total={total}): {endings}")
print(
    "  Note: ending with 'user' msg may indicate user abandoned or was unsatisfied"
)
