import os
import time
import json
import threading
from typing import Callable, Optional

class DaemonLogTailer:
    """
    Watches daemon_events.jsonl using inotify-style polling.
    Calls on_event_callback(event_dict) for each new line appended.
    Thread-safe. Can be used standalone or imported.
    """
    
    LOG_PATH = '/home/snuffleupagus/teamwork_projects/axiom_zero_audit/dev_control_center/daemon_events.jsonl'
    
    def __init__(self, on_event: Callable[[dict], None], poll_interval: float = 0.5):
        self.on_event = on_event
        self.poll_interval = poll_interval
        self._thread: Optional[threading.Thread] = None
        self._running = False
        self._file_pos = 0  # byte offset to resume from
    
    def start(self):
        """Start background tail thread. Seeks to end of file first (only new events)."""
        if os.path.exists(self.LOG_PATH):
            with open(self.LOG_PATH, 'rb') as f:
                f.seek(0, 2)  # seek to end
                self._file_pos = f.tell()
        self._running = True
        self._thread = threading.Thread(target=self._tail_loop, daemon=True)
        self._thread.start()
    
    def stop(self):
        self._running = False
    
    def _tail_loop(self):
        while self._running:
            try:
                if os.path.exists(self.LOG_PATH):
                    with open(self.LOG_PATH, 'r', encoding='utf-8') as f:
                        f.seek(self._file_pos)
                        for line in f:
                            line = line.strip()
                            if line:
                                try:
                                    event = json.loads(line)
                                    self.on_event(event)
                                except json.JSONDecodeError:
                                    pass  # skip malformed lines
                        self._file_pos = f.tell()
            except Exception:
                pass
            time.sleep(self.poll_interval)


class EventFormatter:
    """Formats raw daemon events into human-readable log lines for the GTK console."""
    
    COLORS = {
        'EVENT_BLOCK': '[BLOCKED]',
        'EVENT_ALLOW': '[ALLOWED]',
        'EVENT_CRED_AUDIT': '[AUDIT]',
        'EVENT_THREAT_INTEL': '[THREAT]',
        'EVENT_KILLSWITCH': '[KILLSWITCH]',
        'EVENT_PING': '[PING]',
    }
    
    @staticmethod
    def format(event: dict) -> str:
        """Returns a single formatted log line string."""
        ts = event.get('timestamp', '?')[-8:]  # last 8 chars = HH:MM:SS from ISO
        etype = event.get('type', 'UNKNOWN')
        client_id = event.get('client_id', 'unknown')
        payload = event.get('payload', {})
        
        label = EventFormatter.COLORS.get(etype, f'[{etype}]')
        
        if etype == 'EVENT_BLOCK':
            ip = payload.get('ip', '?')
            bot_class = payload.get('bot_class', '?')
            latency = payload.get('latency_ms', 0)
            return f'[{ts}] {label} {client_id} | IP:{ip} | Class:{bot_class} | {latency:.1f}ms'
        elif etype == 'EVENT_ALLOW':
            ip = payload.get('ip', '?')
            return f'[{ts}] {label} {client_id} | IP:{ip} | HUMAN_VERIFIED'
        elif etype == 'EVENT_CRED_AUDIT':
            status = payload.get('status', '?')
            return f'[{ts}] {label} {client_id} | Credential Status: {status}'
        elif etype == 'EVENT_THREAT_INTEL':
            risk = payload.get('risk_level', '?')
            return f'[{ts}] {label} | Threat Intel: {risk}'
        elif etype == 'EVENT_KILLSWITCH':
            target = payload.get('target_id', payload.get('company_name', client_id))
            reason = payload.get('reason', 'SUBSCRIPTION_REVOKED')
            return f'[{ts}] {label} {client_id} | TARGET:{target} | STATUS:QUARANTINED | Reason:{reason}'
        else:
            return f'[{ts}] {label} {json.dumps(payload)[:60]}'


if __name__ == '__main__':
    # Demo: print any new events to stdout
    print(f'[LOG TAIL] Watching: {DaemonLogTailer.LOG_PATH}')
    
    def print_event(event):
        line = EventFormatter.format(event)
        print(line)
    
    tailer = DaemonLogTailer(on_event=print_event)
    tailer.start()
    
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        tailer.stop()
        print('\n[LOG TAIL] Stopped.')
