#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
// PURPOSE: Atomic Transaction Manager for PULSE Brain.
// [Phase 1.1: Transaction Semantics]
"""

import sys
import json
import logging
import time
from datetime import datetime, timezone
from pathlib import Path

SCRIPT_DIR = Path(__file__).resolve().parent
ROOT_DIR = SCRIPT_DIR.parent.parent
from typing import List, Dict, Any, Optional

# Add Utilities to path

from pulse.core.brain_utils import load_json, save_json
from pulse.core.pulse_crdt import EvidenceCRDT
from pulse.core.pulse_crypto import PulseCrypto

class BrainTransaction:
    """
    // Handles atomic updates to evidence logs.
    // Logic: Pre-validate -> Seal (Crypto) -> Merge (CRDT) -> Post-validate -> Commit.
    """

    def __init__(self, agent_id: str = "gemini_cli"):
        self.agent_id = agent_id
        self.crdt = EvidenceCRDT()
        self.crypto = PulseCrypto()
        self.log_dir = ROOT_DIR / "state"
        self.log_file = self.log_dir / "transaction_audit.json"

    def execute(self, file_path: Path, new_evidence: List[Dict[str, Any]]) -> bool:
        """
        // Executes an atomic update on a memory file.
        // Returns True if successful, False if aborted.
        """
        try:
            # 1. READ
            if not file_path.exists():
                current_data = []
            else:
                current_data = load_json(file_path)
            
            # 2. SEAL & SIGN (Phase 1.2)
            # Every new item is signed by the agent
            sealed_evidence = [self.crypto.seal(item, self.agent_id) for item in new_evidence]
            
            # 3. MERGE (CRDT LWW)
            # Merges existing data with the newly signed evidence
            merged_data = self.crdt.merge(current_data, sealed_evidence)
            
            # 4. INTEGRITY CHECK
            if not self._validate_integrity(merged_data):
                return False

            # 4. COMMIT
            save_json(file_path, merged_data)
            
            # 5. AUDIT
            self._log_transaction(file_path, len(new_evidence))
            return True

        except Exception as e:
            print(f"Transaction Error: {str(e)}")
            return False

    def _validate_integrity(self, data: List[Dict[str, Any]]) -> bool:
        """// Basic integrity check."""
        return isinstance(data, list) and all(isinstance(x, dict) for x in data)

    def _log_transaction(self, file_path: Path, count: int):
        """// Logs transaction metadata to state/transaction_audit.json."""
        audit_entry = {
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "agent_id": self.agent_id,
            "file": str(file_path.name),
            "items_pushed": count
        }
        
        log_data = []
        if self.log_file.exists():
            log_data = load_json(self.log_file)
            if not isinstance(log_data, list): log_data = []
            
        log_data.append(audit_entry)
        # Keep last 100 transactions
        save_json(self.log_file, log_data[-100:])
        print(f"  [TX_COMMIT] {audit_entry['timestamp']} | Agent: {self.agent_id} | File: {audit_entry['file']}")

if __name__ == "__main__":
    # Test Transaction
    tx = BrainTransaction()
    test_file = Path(ROOT_DIR / "state" / "test_tx.json")
    
    evidence = [{"evidence": "Neural path established", "timestamp": time.time()}]
    success = tx.execute(test_file, evidence)
    
    if success:
        print("Transaction Test: PASSED")
        # Cleanup
        if test_file.exists(): test_file.unlink()
    else:
        print("Transaction Test: FAILED")