#!/usr/bin/env python3
"""
Cache Configuration for Local Timmy
Issue #103 — Cache Everywhere

Configuration for all cache tiers with sensible defaults.
"""

from typing import Dict, Any


# TTL Configuration (in seconds)
TTL_CONFIG = {
    # Tool result cache TTLs
    "tools": {
        "system_info": 60,
        "disk_usage": 120,
        "git_status": 30,
        "git_log": 300,
        "health_check": 60,
        "gitea_list_issues": 120,
        "file_read": 30,
        "process_list": 30,
        "service_status": 60,
        "http_get": 300,
        "http_post": 0,  # Don't cache POSTs by default
    },
    
    # Response cache TTLs by query type
    "responses": {
        "status_check": 60,      # System status queries
        "factual": 3600,         # Factual questions
        "code": 0,               # Code generation (never cache)
        "analysis": 600,         # Analysis results
        "creative": 0,           # Creative writing (never cache)
    },
    
    # Embedding cache (no TTL, uses file mtime)
    "embeddings": None,
    
    # HTTP cache TTLs
    "http": {
        "gitea_api": 120,
        "static_content": 86400,  # 24 hours
        "dynamic_content": 60,
    }
}


# Cache size limits
SIZE_LIMITS = {
    "lru_memory_entries": 1000,    # In-memory LRU cache
    "response_disk_mb": 100,        # Response cache database
    "tool_disk_mb": 50,             # Tool cache database
    "embedding_disk_mb": 500,       # Embedding cache database
    "http_disk_mb": 50,             # HTTP cache database
}


# Cache paths (relative to ~/.timmy/)
CACHE_PATHS = {
    "base": "cache",
    "responses": "cache/responses.db",
    "tools": "cache/tool_cache.db",
    "embeddings": "cache/embeddings.db",
    "http": "cache/http_cache.db",
}


# Tool invalidation rules (which tools invalidate others)
INVALIDATION_RULES = {
    "git_commit": ["git_status", "git_log"],
    "git_pull": ["git_status", "git_log"],
    "git_push": ["git_status"],
    "file_write": ["file_read"],
    "file_delete": ["file_read"],
    "gitea_create_issue": ["gitea_list_issues"],
    "gitea_comment": ["gitea_list_issues"],
    "gitea_close_issue": ["gitea_list_issues"],
}


# Refusal patterns for semantic refusal detection
REFUSAL_PATTERNS = [
    r"I (?:can't|cannot|am unable to|must decline)",
    r"against my (?:guidelines|policy|programming)",
    r"I'm not (?:able|comfortable|designed) to",
    r"I (?:apologize|'m sorry),? but I (?:can't|cannot)",
    r"I don't (?:know|have information about)",
    r"I'm not sure",
    r"I cannot assist",
]


# Template cache configuration
TEMPLATE_CONFIG = {
    "paths": {
        "minimal": "~/.timmy/templates/minimal.txt",
        "standard": "~/.timmy/templates/standard.txt",
        "deep": "~/.timmy/templates/deep.txt",
    },
    "auto_load": ["minimal", "standard", "deep"],
}


# Performance targets
TARGETS = {
    "tool_cache_hit_rate": 0.30,      # 30%
    "response_cache_hit_rate": 0.20,  # 20%
    "embedding_cache_hit_rate": 0.80, # 80%
    "max_cache_memory_mb": 100,
    "cleanup_interval_seconds": 3600,  # Hourly cleanup
}


def get_ttl(cache_type: str, key: str) -> int:
    """Get TTL for a specific cache entry type."""
    if cache_type == "tools":
        return TTL_CONFIG["tools"].get(key, 60)
    elif cache_type == "responses":
        return TTL_CONFIG["responses"].get(key, 300)
    elif cache_type == "http":
        return TTL_CONFIG["http"].get(key, 300)
    return 60


def get_invalidation_deps(tool_name: str) -> list:
    """Get list of tools to invalidate when this tool runs."""
    return INVALIDATION_RULES.get(tool_name, [])


def is_cacheable(tool_name: str) -> bool:
    """Check if a tool result should be cached."""
    return tool_name in TTL_CONFIG["tools"] and TTL_CONFIG["tools"][tool_name] > 0


def get_config() -> Dict[str, Any]:
    """Get complete cache configuration."""
    return {
        "ttl": TTL_CONFIG,
        "sizes": SIZE_LIMITS,
        "paths": CACHE_PATHS,
        "invalidation": INVALIDATION_RULES,
        "templates": TEMPLATE_CONFIG,
        "targets": TARGETS,
    }


if __name__ == "__main__":
    import json
    print(json.dumps(get_config(), indent=2))
