#!/usr/bin/env python3
"""
Urgency Router — classifies incoming tasks and recommends model paths.

Usage: python3 urgency-router.py <user_message>
Output: JSON with urgency classification and recommended model path.

Detection order: savings → this_week → instant → today → default(today)
This prevents "need" from matching "instant" when user says "no rush save cost".
"""

import json
import os
import re
import sys
from datetime import datetime

INSTANT_SIGNALS = [
    "urgent", "asap", "fast", "quick", "now", "immediately",
    "right now", "right away", "emergency", "critical",
    "hurry", "rush", "speed", "quickly", "promptly",
]

TODAY_SIGNALS = [
    "today", "tonight", "by tonight", "before bed",
    "by end of day", "eod", "deadline", "due today",
    "need it today", "finish today",
]

THIS_WEEK_SIGNALS = [
    "this week", "sometime this week", "whenever",
    "take your time", "when you can",
    "low priority", "background",
]

SAVINGS_SIGNALS = [
    "no rush", "save cost", "cheap", "free", "local only",
    "don't spend", "minimize cost", "budget",
    "free tier", "no api", "local first",
]

SQL_PATTERNS = [
    r"\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|FROM|WHERE|JOIN)\b",
    r"\b(SUM|COUNT|AVG|MAX|MIN|GROUP BY|ORDER BY|HAVING)\b",
    r"\b(CASE\s+WHEN|COALESCE|ISNULL|NULLIF)\b",
]

DAX_PATTERNS = [
    r"\b(CALCULATE|FILTER|SUMX|AVERAGEX|COUNTX|ALL|VALUES|RELATED)\b",
    r"\b(SUMMARIZE|ADDCOLUMNS|FILTER|DISTINCT|INTERSECT)\b",
]

VBA_PATTERNS = [
    r"\b(Sub|Function|Dim|As|Set|With|For\s+Each|Next|If\s+Then|End\s+Sub|End\s+Function)\b",
    r"\b(Range|Cells|Worksheet|Workbook|Sheets|Application)\b",
    r"\b(MsgBox|InputBox|Debug\.Print)\b",
]

LOG_FILE = os.path.expanduser("~/.hermes/logs/urgency-router.log")

def detect_sql_dax_vba(text):
    text_lower = text.lower()
    sql_score = sum(1 for p in SQL_PATTERNS if re.search(p, text, re.IGNORECASE))
    dax_score = sum(1 for p in DAX_PATTERNS if re.search(p, text, re.IGNORECASE))
    vba_score = sum(1 for p in VBA_PATTERNS if re.search(p, text, re.IGNORECASE))
    types = []
    if sql_score >= 2: types.append("SQL")
    if dax_score >= 2: types.append("DAX")
    if vba_score >= 2: types.append("VBA")
    return types

def classify_urgency(text):
    text_lower = text.lower()
    # Savings FIRST (most specific, prevents "need" matching instant)
    for signal in SAVINGS_SIGNALS:
        if signal in text_lower:
            return "savings"
    for signal in THIS_WEEK_SIGNALS:
        if signal in text_lower:
            return "this_week"
    for signal in INSTANT_SIGNALS:
        if signal in text_lower:
            return "instant"
    for signal in TODAY_SIGNALS:
        if signal in text_lower:
            return "today"
    return "today"

def recommend_path(urgency, has_sql_dax_vba, has_chatgpt_auth):
    if has_sql_dax_vba:
        if urgency == "instant" and has_chatgpt_auth:
            return {"primary": "chatgpt", "fallback": "qwen/qwen3-coder", "reason": "SQL/DAX/VBA with urgency — ChatGPT Auth for speed"}
        elif urgency == "instant":
            return {"primary": "qwen/qwen3-coder", "fallback": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "reason": "SQL/DAX/VBA with urgency — OpenRouter coder first"}
        else:
            return {"primary": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "fallback": "qwen/qwen3-coder", "reason": "SQL/DAX/VBA without urgency — local coder first"}
    if urgency == "instant":
        if has_chatgpt_auth:
            return {"primary": "chatgpt", "fallback": "qwen/qwen3-coder", "reason": "Urgent task — ChatGPT Auth for speed"}
        else:
            return {"primary": "qwen/qwen3-coder", "fallback": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "reason": "Urgent task — OpenRouter coder first"}
    if urgency == "today":
        return {"primary": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "fallback": "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", "reason": "Today deadline — local coder first"}
    if urgency == "this_week":
        return {"primary": "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", "fallback": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "reason": "This week — heavy lifter for complex work"}
    if urgency == "savings":
        return {"primary": "Qwen2.5-Coder-7B-Instruct-Q5_K_M.gguf", "fallback": "Qwen3-8B-Q5_K_M.gguf", "reason": "Cost-conscious — fast local models only"}
    return {"primary": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf", "fallback": "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", "reason": "Default — balanced local coding"}

def main():
    if len(sys.argv) < 2:
        print(json.dumps({"error": "Usage: urgency-router.py <user_message>"}), file=sys.stderr)
        sys.exit(1)
    message = " ".join(sys.argv[1:])
    urgency = classify_urgency(message)
    sql_dax_vba = detect_sql_dax_vba(message)
    has_chatgpt = os.path.exists(os.path.expanduser("~/.claude/credentials"))
    path = recommend_path(urgency, len(sql_dax_vba) > 0, has_chatgpt)
    result = {
        "urgency": urgency,
        "task_types": sql_dax_vba,
        "chatgpt_available": has_chatgpt,
        "recommended_path": path,
        "timestamp": datetime.now().isoformat(),
    }
    os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
    with open(LOG_FILE, "a") as f:
        f.write(f"[{result['timestamp']}] urgency={urgency} types={sql_dax_vba} path={path['primary']}\n")
    print(json.dumps(result, indent=2))

if __name__ == "__main__":
    main()
