#!/usr/bin/env python3
"""Clean up stale session tool states.

This script cleans up the session_tool_states.json file which can grow
large from test runs creating many sessions.

Usage:
    # Preview what would be cleaned (dry run)
    python scripts/cleanup_session_states.py

    # Actually clean up (keep sessions from last hour)
    python scripts/cleanup_session_states.py --execute

    # Clean sessions older than 24 hours
    python scripts/cleanup_session_states.py --execute --hours 24

    # Clean ALL sessions (reset to empty)
    python scripts/cleanup_session_states.py --execute --all
"""

import argparse
import json
import os
import sys
from datetime import datetime, timedelta
from pathlib import Path

# Add project root to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def get_session_file_path() -> Path:
    """Get the path to the session tool states file."""
    try:
        from config.settings import settings

        return settings.session_tool_state_path
    except Exception:
        # Fallback to default location
        return Path("credentials/session_tool_states.json")


def load_sessions(file_path: Path) -> dict:
    """Load sessions from file."""
    if not file_path.exists():
        return {}

    try:
        with open(file_path, "r") as f:
            return json.load(f)
    except (json.JSONDecodeError, IOError) as e:
        print(f"Error loading sessions: {e}")
        return {}


def save_sessions(file_path: Path, sessions: dict) -> bool:
    """Save sessions to file."""
    try:
        file_path.parent.mkdir(parents=True, exist_ok=True)
        with open(file_path, "w") as f:
            json.dump(sessions, f, indent=2, default=str)
        return True
    except IOError as e:
        print(f"Error saving sessions: {e}")
        return False


def cleanup_sessions(
    max_age_hours: float = 1.0,
    execute: bool = False,
    clear_all: bool = False,
) -> dict:
    """Clean up old session states.

    Args:
        max_age_hours: Maximum age in hours for sessions to keep
        execute: If True, actually delete; if False, just preview
        clear_all: If True, clear ALL sessions regardless of age

    Returns:
        Summary of cleanup operation
    """
    file_path = get_session_file_path()
    sessions = load_sessions(file_path)

    if not sessions:
        return {
            "file_path": str(file_path),
            "total_sessions": 0,
            "sessions_to_remove": 0,
            "sessions_to_keep": 0,
            "executed": False,
            "message": "No sessions found",
        }

    total = len(sessions)
    cutoff_time = datetime.now() - timedelta(hours=max_age_hours)

    # Categorize sessions
    to_keep = {}
    to_remove = {}

    for session_id, data in sessions.items():
        if clear_all:
            to_remove[session_id] = data
        else:
            last_accessed_str = data.get("last_accessed")
            if last_accessed_str:
                try:
                    last_accessed = datetime.fromisoformat(last_accessed_str)
                    if last_accessed < cutoff_time:
                        to_remove[session_id] = data
                    else:
                        to_keep[session_id] = data
                except (ValueError, TypeError):
                    # Invalid date format, mark for removal
                    to_remove[session_id] = data
            else:
                # No timestamp, mark for removal
                to_remove[session_id] = data

    result = {
        "file_path": str(file_path),
        "file_size_mb": (
            file_path.stat().st_size / (1024 * 1024) if file_path.exists() else 0
        ),
        "total_sessions": total,
        "sessions_to_remove": len(to_remove),
        "sessions_to_keep": len(to_keep),
        "cutoff_time": cutoff_time.isoformat() if not clear_all else "N/A (clear all)",
        "executed": execute,
    }

    if execute:
        if save_sessions(file_path, to_keep):
            result["new_file_size_mb"] = (
                file_path.stat().st_size / (1024 * 1024) if to_keep else 0
            )
            result["message"] = (
                f"Removed {len(to_remove)} sessions, kept {len(to_keep)}"
            )
        else:
            result["message"] = "Failed to save cleaned sessions"
    else:
        result["message"] = (
            f"Would remove {len(to_remove)} sessions, keep {len(to_keep)} (dry run)"
        )

    return result


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        description="Clean up stale session tool states",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=__doc__,
    )
    parser.add_argument(
        "--execute",
        action="store_true",
        help="Actually delete sessions (default is dry run)",
    )
    parser.add_argument(
        "--hours",
        type=float,
        default=1.0,
        help="Keep sessions newer than this many hours (default: 1)",
    )
    parser.add_argument(
        "--all",
        action="store_true",
        help="Clear ALL sessions regardless of age",
    )

    args = parser.parse_args()

    print("\n" + "=" * 60)
    print("SESSION TOOL STATES CLEANUP")
    print("=" * 60)

    result = cleanup_sessions(
        max_age_hours=args.hours,
        execute=args.execute,
        clear_all=args.all,
    )

    print(f"   File: {result['file_path']}")
    if result.get("file_size_mb"):
        print(f"   File size: {result['file_size_mb']:.2f} MB")
    print(f"   Total sessions: {result['total_sessions']}")
    print(f"   Sessions to remove: {result['sessions_to_remove']}")
    print(f"   Sessions to keep: {result['sessions_to_keep']}")
    if result.get("cutoff_time"):
        print(f"   Cutoff time: {result['cutoff_time']}")
    print(f"   Mode: {'EXECUTE' if result['executed'] else 'DRY RUN'}")
    print()
    print(f"   {result['message']}")

    if result.get("new_file_size_mb") is not None:
        print(f"   New file size: {result['new_file_size_mb']:.2f} MB")

    print("=" * 60 + "\n")

    if not args.execute and result["sessions_to_remove"] > 0:
        print("Run with --execute to actually remove sessions")


if __name__ == "__main__":
    main()
