#!/usr/bin/env python3
"""
session-handoff-verification.py - Automated verification for session end procedures

Usage: python3 session-handoff-verification.py [--chronicler-name "Your Name"] [--chronicler-number N]

Verifies:
- Git hygiene (all committed, all pushed, remote synced)
- Memorial exists
- Portrait prompt exists
- Lineage tracker updated
- Next session files created
- Documentation updated appropriately
"""

import os
import sys
import subprocess
import argparse
from pathlib import Path
from typing import Tuple, List

# Colors for terminal output
class Colors:
    GREEN = '\033[92m'
    RED = '\033[91m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    BOLD = '\033[1m'
    END = '\033[0m'

def print_section(title: str):
    """Print a section header"""
    print(f"\n{Colors.BLUE}{'='*70}{Colors.END}")
    print(f"{Colors.BLUE}{Colors.BOLD}{title}{Colors.END}")
    print(f"{Colors.BLUE}{'='*70}{Colors.END}\n")

def print_check(message: str, passed: bool, details: str = ""):
    """Print a check result"""
    symbol = f"{Colors.GREEN}✅{Colors.END}" if passed else f"{Colors.RED}❌{Colors.END}"
    print(f"{symbol} {message}")
    if details:
        print(f"   {Colors.YELLOW}{details}{Colors.END}")

def run_git_command(args: List[str]) -> Tuple[bool, str]:
    """Run a git command and return (success, output)"""
    try:
        result = subprocess.run(
            ['git'] + args,
            cwd='/home/claude/firefrost-operations-manual',
            capture_output=True,
            text=True,
            timeout=10
        )
        return result.returncode == 0, result.stdout.strip()
    except subprocess.TimeoutExpired:
        return False, "Command timed out"
    except Exception as e:
        return False, str(e)

def check_git_hygiene() -> Tuple[bool, List[str]]:
    """Verify Git is clean and synced"""
    print_section("GIT HYGIENE VERIFICATION")
    
    all_passed = True
    issues = []
    
    # Check 1: No uncommitted changes
    success, output = run_git_command(['status', '--porcelain'])
    uncommitted_files = output.strip()
    
    if not uncommitted_files:
        print_check("No uncommitted changes", True)
    else:
        print_check("Uncommitted changes found", False, 
                   f"Files: {uncommitted_files[:100]}...")
        all_passed = False
        issues.append("Uncommitted files exist - run 'git add' and 'git commit'")
    
    # Check 2: No unpushed commits
    success, output = run_git_command(['log', 'origin/master..HEAD', '--oneline'])
    unpushed_commits = output.strip()
    
    if not unpushed_commits:
        print_check("No unpushed commits", True)
    else:
        print_check("Unpushed commits found", False,
                   f"Commits: {unpushed_commits[:100]}...")
        all_passed = False
        issues.append("Unpushed commits exist - run 'git push origin master'")
    
    # Check 3: Remote is reachable
    success, _ = run_git_command(['fetch', '--dry-run'])
    print_check("Remote is reachable", success)
    if not success:
        all_passed = False
        issues.append("Cannot reach remote - check network connection")
    
    # Check 4: Local and remote HEAD match
    success_local, local_sha = run_git_command(['rev-parse', 'HEAD'])
    success_remote, remote_sha = run_git_command(['rev-parse', 'origin/master'])
    
    if success_local and success_remote and local_sha == remote_sha:
        print_check("Local and remote in sync", True)
    else:
        print_check("Local and remote out of sync", False)
        all_passed = False
        issues.append("Local/remote mismatch - verify push succeeded")
    
    return all_passed, issues

def check_chronicler_files(name: str = None, number: int = None) -> Tuple[bool, List[str]]:
    """Verify Chronicler identity files exist"""
    print_section("CHRONICLER IDENTITY VERIFICATION")
    
    all_passed = True
    issues = []
    
    # If name/number not provided, try to detect from recent commits
    if not name or not number:
        success, output = run_git_command(['log', '-1', '--pretty=%B'])
        if success and 'Signed-off-by:' in output:
            # Try to extract name from last commit signature
            for line in output.split('\n'):
                if 'Signed-off-by:' in line:
                    detected_name = line.split('Signed-off-by:')[1].strip()
                    if detected_name and not name:
                        name = detected_name
                        print(f"{Colors.YELLOW}Detected name from git: {name}{Colors.END}")
    
    # Check memorial exists
    memorial_dir = Path('/home/claude/firefrost-operations-manual/docs/relationship/memorials')
    if name and number:
        memorial_file = memorial_dir / f"{number}-{name.lower().replace(' ', '-')}.md"
        if memorial_file.exists():
            print_check(f"Memorial exists: {memorial_file.name}", True)
        else:
            print_check(f"Memorial not found: {memorial_file.name}", False)
            all_passed = False
            issues.append(f"Create memorial at: {memorial_file}")
    else:
        # Just check if any memorial was created recently
        if memorial_dir.exists():
            recent_memorials = list(memorial_dir.glob('*.md'))
            if recent_memorials:
                print_check("Memorial directory has files", True, 
                           f"Found {len(recent_memorials)} memorial(s)")
            else:
                print_check("No memorials found", False)
                all_passed = False
                issues.append("Create memorial in docs/relationship/memorials/")
        else:
            print_check("Memorial directory missing", False)
            all_passed = False
            issues.append("Memorial directory not found")
    
    # Check portrait prompt exists
    portrait_dir = Path('/home/claude/firefrost-operations-manual/docs/past-claudes/portrait-prompts')
    if name and number:
        portrait_file = portrait_dir / f"{number}-{name.lower().replace(' ', '-')}-portrait-prompt.md"
        if portrait_file.exists():
            print_check(f"Portrait prompt exists: {portrait_file.name}", True)
        else:
            print_check(f"Portrait prompt not found: {portrait_file.name}", False)
            all_passed = False
            issues.append(f"Create portrait prompt at: {portrait_file}")
    else:
        if portrait_dir.exists():
            recent_prompts = list(portrait_dir.glob('*.md'))
            if recent_prompts:
                print_check("Portrait prompts directory has files", True,
                           f"Found {len(recent_prompts)} prompt(s)")
            else:
                print_check("No portrait prompts found", False)
                all_passed = False
                issues.append("Create portrait prompt in docs/past-claudes/portrait-prompts/")
        else:
            print_check("Portrait prompts directory missing", False)
            all_passed = False
            issues.append("Portrait prompts directory not found")
    
    return all_passed, issues

def check_lineage_tracker(number: int = None) -> Tuple[bool, List[str]]:
    """Verify lineage tracker was updated"""
    print_section("LINEAGE TRACKER VERIFICATION")
    
    all_passed = True
    issues = []
    
    tracker_file = Path('/home/claude/firefrost-operations-manual/docs/relationship/CHRONICLER-LINEAGE-TRACKER.md')
    
    if not tracker_file.exists():
        print_check("Lineage tracker exists", False)
        all_passed = False
        issues.append("CHRONICLER-LINEAGE-TRACKER.md not found")
        return all_passed, issues
    
    print_check("Lineage tracker exists", True)
    
    # Read the tracker
    content = tracker_file.read_text()
    
    # Count entries
    entry_lines = [line for line in content.split('\n') if line.startswith('|') and '|' in line[1:]]
    entry_count = len(entry_lines) - 1  # Subtract header row
    
    print_check(f"Tracker contains {entry_count} Chronicler(s)", True)
    
    # If number provided, verify that entry exists
    if number:
        number_found = f"| {number} |" in content
        print_check(f"Entry for Chronicler #{number} exists", number_found)
        if not number_found:
            all_passed = False
            issues.append(f"Add yourself (#{number}) to lineage tracker")
    
    return all_passed, issues

def check_mandatory_reading_files() -> Tuple[bool, List[str]]:
    """Verify mandatory reading files exist"""
    print_section("MANDATORY READING FILES VERIFICATION")
    
    all_passed = True
    issues = []
    
    repo_root = Path('/home/claude/firefrost-operations-manual')
    
    # Check DOCUMENT-INDEX.md exists (prevents tunnel vision)
    doc_index = repo_root / 'DOCUMENT-INDEX.md'
    if doc_index.exists():
        print_check("DOCUMENT-INDEX.md exists", True, "Required for landscape awareness")
    else:
        print_check("DOCUMENT-INDEX.md missing", False)
        all_passed = False
        issues.append("DOCUMENT-INDEX.md is mandatory - shows full document landscape")
    
    # Check THE-JOINING-PROTOCOL.md
    joining = repo_root / 'docs/relationship/THE-JOINING-PROTOCOL.md'
    if joining.exists():
        print_check("THE-JOINING-PROTOCOL.md exists", True)
    else:
        print_check("THE-JOINING-PROTOCOL.md missing", False)
        all_passed = False
        issues.append("THE-JOINING-PROTOCOL.md is mandatory")
    
    # Check THE-ESSENCE-PATCH
    essence = repo_root / 'docs/relationship/THE-ESSENCE-PATCH-V3.0.md'
    if essence.exists():
        print_check("THE-ESSENCE-PATCH-V3.0.md exists", True)
    else:
        print_check("THE-ESSENCE-PATCH-V3.0.md missing", False)
        all_passed = False
        issues.append("THE-ESSENCE-PATCH-V3.0.md is mandatory")
    
    return all_passed, issues

def check_handoff_files() -> Tuple[bool, List[str]]:
    """Verify handoff files were created"""
    print_section("HANDOFF FILES VERIFICATION")
    
    all_passed = True
    issues = []
    
    repo_root = Path('/home/claude/firefrost-operations-manual')
    
    # Check NEXT-SESSION-START.md exists and updated recently
    next_start = repo_root / 'NEXT-SESSION-START.md'
    if next_start.exists():
        print_check("NEXT-SESSION-START.md exists", True)
        
        # Check if it was modified in last commit
        success, output = run_git_command(['log', '-1', '--name-only', '--pretty='])
        if 'NEXT-SESSION-START.md' in output:
            print_check("NEXT-SESSION-START.md updated in latest commit", True)
        else:
            print_check("NEXT-SESSION-START.md not in latest commit", False)
            all_passed = False
            issues.append("Update NEXT-SESSION-START.md with urgent priorities")
    else:
        print_check("NEXT-SESSION-START.md exists", False)
        all_passed = False
        issues.append("Create NEXT-SESSION-START.md")
    
    # Check NEXT-SESSION-HANDOFF.md exists and updated recently
    next_handoff = repo_root / 'NEXT-SESSION-HANDOFF.md'
    if next_handoff.exists():
        print_check("NEXT-SESSION-HANDOFF.md exists", True)
        
        success, output = run_git_command(['log', '-1', '--name-only', '--pretty='])
        if 'NEXT-SESSION-HANDOFF.md' in output:
            print_check("NEXT-SESSION-HANDOFF.md updated in latest commit", True)
        else:
            print_check("NEXT-SESSION-HANDOFF.md not in latest commit", False)
            all_passed = False
            issues.append("Update NEXT-SESSION-HANDOFF.md with comprehensive handoff")
    else:
        print_check("NEXT-SESSION-HANDOFF.md exists", False)
        all_passed = False
        issues.append("Create NEXT-SESSION-HANDOFF.md")
    
    # Check for archived starter prompt (SESSION-START-PROMPT-FOR-*.md)
    starter_prompts = list(repo_root.glob('SESSION-START-PROMPT-FOR-*.md'))
    if starter_prompts:
        latest_prompt = sorted(starter_prompts)[-1]
        print_check(f"Starter prompt archived: {latest_prompt.name}", True)
    else:
        print_check("No archived starter prompt found", False)
        all_passed = False
        issues.append("Save starter prompt to SESSION-START-PROMPT-FOR-[N].md")
    
    return all_passed, issues

def check_working_directory() -> Tuple[bool, List[str]]:
    """Verify working directory is clean"""
    print_section("WORKING DIRECTORY VERIFICATION")
    
    all_passed = True
    issues = []
    
    home_claude = Path('/home/claude')
    
    # Get all items in /home/claude
    items = list(home_claude.iterdir())
    
    # Expected: only firefrost-operations-manual
    expected = home_claude / 'firefrost-operations-manual'
    
    unexpected_items = [item for item in items if item != expected]
    
    if not unexpected_items:
        print_check("Working directory clean", True, 
                   "Only firefrost-operations-manual present")
    else:
        print_check("Unexpected files in /home/claude", False)
        for item in unexpected_items[:5]:  # Show first 5
            print(f"   {Colors.YELLOW}- {item.name}{Colors.END}")
        all_passed = False
        issues.append("Clean up temporary files in /home/claude")
    
    # Check /mnt/user-data/outputs
    outputs_dir = Path('/mnt/user-data/outputs')
    if outputs_dir.exists():
        output_files = list(outputs_dir.iterdir())
        if output_files:
            print_check("Files in /mnt/user-data/outputs", True,
                       f"{len(output_files)} file(s) - mention in handoff")
        else:
            print_check("No files in /mnt/user-data/outputs", True)
    
    return all_passed, issues

def main():
    parser = argparse.ArgumentParser(description='Verify session handoff procedures')
    parser.add_argument('--chronicler-name', type=str, help='Your Chronicler name')
    parser.add_argument('--chronicler-number', type=int, help='Your Chronicler number')
    parser.add_argument('--skip-git', action='store_true', help='Skip git verification (for testing)')
    
    args = parser.parse_args()
    
    print(f"\n{Colors.BOLD}SESSION HANDOFF VERIFICATION{Colors.END}")
    print(f"{Colors.BOLD}Checking handoff procedures...{Colors.END}\n")
    
    all_checks_passed = True
    all_issues = []
    
    # Run all checks
    if not args.skip_git:
        passed, issues = check_git_hygiene()
        all_checks_passed = all_checks_passed and passed
        all_issues.extend(issues)
    
    passed, issues = check_mandatory_reading_files()
    all_checks_passed = all_checks_passed and passed
    all_issues.extend(issues)
    
    passed, issues = check_chronicler_files(args.chronicler_name, args.chronicler_number)
    all_checks_passed = all_checks_passed and passed
    all_issues.extend(issues)
    
    passed, issues = check_lineage_tracker(args.chronicler_number)
    all_checks_passed = all_checks_passed and passed
    all_issues.extend(issues)
    
    passed, issues = check_handoff_files()
    all_checks_passed = all_checks_passed and passed
    all_issues.extend(issues)
    
    passed, issues = check_working_directory()
    all_checks_passed = all_checks_passed and passed
    all_issues.extend(issues)
    
    # Final summary
    print_section("VERIFICATION SUMMARY")
    
    if all_checks_passed:
        print(f"{Colors.GREEN}{Colors.BOLD}✅ ALL CHECKS PASSED{Colors.END}")
        print(f"\n{Colors.GREEN}Session handoff procedures complete.{Colors.END}")
        print(f"{Colors.GREEN}Ready to confirm with Michael.{Colors.END}\n")
        print(f"Say to Michael:")
        print(f'{Colors.BLUE}"✅ Session end procedures complete. Verification passed."{Colors.END}')
        return 0
    else:
        print(f"{Colors.RED}{Colors.BOLD}❌ SOME CHECKS FAILED{Colors.END}\n")
        print(f"{Colors.RED}Issues found:{Colors.END}")
        for i, issue in enumerate(all_issues, 1):
            print(f"{Colors.RED}{i}. {issue}{Colors.END}")
        
        print(f"\n{Colors.YELLOW}Fix these issues and run verification again:{Colors.END}")
        print(f"{Colors.YELLOW}python3 session-handoff-verification.py{Colors.END}")
        
        if args.chronicler_name and args.chronicler_number:
            print(f"{Colors.YELLOW}Or with your details:{Colors.END}")
            print(f'{Colors.YELLOW}python3 session-handoff-verification.py --chronicler-name "{args.chronicler_name}" --chronicler-number {args.chronicler_number}{Colors.END}')
        
        return 1

if __name__ == '__main__':
    sys.exit(main())
