#!/usr/bin/env python3
"""
Memory Compression Script

Compresses old daily memory files (>30 days) into monthly summaries.
Keeps the last 30 days of daily files intact.

Usage:
    python3 compress-memory.py [--dry-run] [--days 30]
"""

import os
import re
import json
import argparse
from datetime import datetime, timedelta
from pathlib import Path
from collections import defaultdict

MEMORY_DIR = Path.home() / ".openclaw" / "workspace" / "memory"
ARCHIVE_DIR = MEMORY_DIR / "archive"

def get_daily_files():
    """Find all daily memory files (YYYY-MM-DD.md format)."""
    pattern = re.compile(r"^\d{4}-\d{2}-\d{2}\.md$")
    files = []
    
    for f in MEMORY_DIR.iterdir():
        if f.is_file() and pattern.match(f.name):
            date_str = f.stem  # YYYY-MM-DD
            try:
                date = datetime.strptime(date_str, "%Y-%m-%d")
                files.append((date, f))
            except ValueError:
                continue
    
    return sorted(files, key=lambda x: x[0])

def group_by_month(files):
    """Group files by year-month."""
    groups = defaultdict(list)
    for date, filepath in files:
        month_key = date.strftime("%Y-%m")
        groups[month_key].append((date, filepath))
    return groups

def compress_month(month_key, files, dry_run=False):
    """Compress a month's files into a summary."""
    
    # Read all files
    contents = []
    for date, filepath in sorted(files):
        with open(filepath, 'r') as f:
            content = f.read().strip()
            if content:
                contents.append(f"## {date.strftime('%Y-%m-%d')}\n\n{content}")
    
    if not contents:
        return None
    
    # Create archive
    ARCHIVE_DIR.mkdir(exist_ok=True)
    archive_path = ARCHIVE_DIR / f"{month_key}-archive.md"
    
    header = f"# Memory Archive: {month_key}\n\n"
    header += f"*Compressed {len(files)} daily files on {datetime.now().strftime('%Y-%m-%d')}*\n\n"
    header += "---\n\n"
    
    full_content = header + "\n\n---\n\n".join(contents)
    
    if dry_run:
        print(f"[DRY RUN] Would create: {archive_path}")
        print(f"[DRY RUN] Would archive {len(files)} files ({len(full_content)} bytes)")
    else:
        with open(archive_path, 'w') as f:
            f.write(full_content)
        
        # Delete original files
        for date, filepath in files:
            filepath.unlink()
        
        print(f"Created: {archive_path}")
        print(f"Archived {len(files)} files, deleted originals")
    
    return archive_path

def main():
    parser = argparse.ArgumentParser(description="Compress old memory files")
    parser.add_argument("--dry-run", action="store_true", help="Show what would happen without doing it")
    parser.add_argument("--days", type=int, default=30, help="Keep this many days of daily files (default: 30)")
    args = parser.parse_args()
    
    cutoff = datetime.now() - timedelta(days=args.days)
    print(f"Cutoff date: {cutoff.strftime('%Y-%m-%d')} (keeping last {args.days} days)")
    
    all_files = get_daily_files()
    print(f"Found {len(all_files)} daily memory files")
    
    # Split into keep vs compress
    to_keep = [(d, f) for d, f in all_files if d >= cutoff]
    to_compress = [(d, f) for d, f in all_files if d < cutoff]
    
    print(f"Keeping: {len(to_keep)} files (recent)")
    print(f"Compressing: {len(to_compress)} files (older than {args.days} days)")
    
    if not to_compress:
        print("Nothing to compress.")
        return
    
    # Group by month and compress
    months = group_by_month(to_compress)
    
    for month_key in sorted(months.keys()):
        files = months[month_key]
        print(f"\nProcessing {month_key} ({len(files)} files)...")
        compress_month(month_key, files, dry_run=args.dry_run)
    
    print("\nDone!")
    
    # Summary
    if not args.dry_run:
        remaining = len(list(MEMORY_DIR.glob("????-??-??.md")))
        archives = len(list(ARCHIVE_DIR.glob("*-archive.md"))) if ARCHIVE_DIR.exists() else 0
        print(f"\nSummary: {remaining} daily files, {archives} monthly archives")

if __name__ == "__main__":
    main()

# TONY-APPROVED: 2026-03-01 | sha:401e788b
