#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
// PURPOSE: Implements Conflict-free Replicated Data Type (CRDT) logic for evidence logs.
// [Used by: synthesizer.py, auto_capture.py]
"""

import hashlib
import json
from datetime import datetime, timezone
from typing import List, Dict, Any, Optional

class EvidenceCRDT:
    """
    // Last-Write-Wins (LWW) Element Set for multi-agent evidence synchronization.
    // Prevents state corruption when multiple agents write to the same domain.
    """

    @staticmethod
    def generate_id(item: Dict[str, Any]) -> str:
        """// Generates a stable unique ID based on evidence content to prevent duplicates."""
        # Normalize content for hashing: evidence/description + domain
        content = str(item.get("evidence") or item.get("description") or "")
        domain = str(item.get("domain") or "general")
        raw_string = f"{domain}:{content}".strip().lower()
        return hashlib.sha256(raw_string.encode()).hexdigest()

    @staticmethod
    def get_timestamp(item: Dict[str, Any]) -> float:
        """// Extracts Unix timestamp, defaulting to current time if missing."""
        ts = item.get("timestamp") or item.get("date")
        if not ts:
            return datetime.now(timezone.utc).timestamp()
        
        try:
            if isinstance(ts, (int, float)):
                return float(ts)
            # Handle ISO format
            dt = datetime.fromisoformat(str(ts).replace("Z", "+00:00"))
            return dt.timestamp()
        except (ValueError, TypeError):
            return datetime.now(timezone.utc).timestamp()

    def merge(self, local_set: List[Dict[str, Any]], remote_set: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        // Merges two evidence sets using LWW semantics.
        // 1. Identifies unique items via content hash.
        // 2. If same item exists in both, keeps the one with the newer timestamp.
        """
        registry: Dict[str, Dict[str, Any]] = {}

        for item in local_set + remote_set:
            if not isinstance(item, dict):
                continue
                
            item_id = self.generate_id(item)
            item_ts = self.get_timestamp(item)
            
            existing = registry.get(item_id)
            if not existing or item_ts > self.get_timestamp(existing):
                # Update with newer version or add new entry
                item["_crdt_id"] = item_id
                item["_merged_at"] = datetime.now(timezone.utc).isoformat()
                registry[item_id] = item

        # Return sorted by timestamp descending (newest first)
        return sorted(registry.values(), key=lambda x: self.get_timestamp(x), reverse=True)

if __name__ == "__main__":
    # Quick sanity check logic
    crdt = EvidenceCRDT()
    test_a = [{"evidence": "User likes blue", "timestamp": 1000}]
    test_b = [{"evidence": "User likes blue", "timestamp": 2000}] # Newer
    merged = crdt.merge(test_a, test_b)
    print(f"Merged count: {len(merged)} (Expected: 1)")
    print(f"Winner TS: {merged[0]['timestamp']} (Expected: 2000)")
