import asyncio
import re
import hashlib
from datetime import datetime
from typing import Dict, Tuple, Any
from aiva.db_connector import memory  # Assuming this exists

# --- Gate Definitions ---

class GateAlpha:
    """Gate Alpha: Input Validity"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, input_data: str, metadata: Dict, task_description: str) -> Tuple[bool, Dict]:
        """Validates the input data source quality."""
        checks = {}
        
        # Check 1: Input Length (Example)
        checks["input_length_valid"] = len(input_data) > 10  # Arbitrary min length
        
        # Check 2: Data Source Trust (Example - needs real implementation)
        checks["source_trusted"] = metadata.get("source_trust_score", 0) > 0.5

        passed = all(checks.values())
        reasoning = "Input data deemed valid." if passed else "Input data failed validation."

        # Log decision
        await self._log_decision("alpha", passed, checks, task_description, metadata)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str, metadata: Dict):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "metadata": metadata,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")



class GateBeta:
    """Gate Beta: Output Quality"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, output: str, input_data: str, task_description: str) -> Tuple[bool, Dict]:
        """Validates the output data accuracy and completeness."""
        checks = {}

        # Check 1: Completeness (Example - depends on task)
        checks["output_not_empty"] = bool(output.strip())

        # Check 2: Accuracy (Example - keyword presence related to input)
        input_keywords = re.findall(r'\b\w+\b', input_data.lower())
        output_keywords = re.findall(r'\b\w+\b', output.lower())
        checks["keywords_present"] = any(keyword in output_keywords for keyword in input_keywords[:5]) #check first 5 keywords

        passed = all(checks.values())
        reasoning = "Output quality deemed acceptable." if passed else "Output quality failed validation."

        # Log decision
        await self._log_decision("beta", passed, checks, task_description)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")

class GateGamma:
    """Gate Gamma: Insight Purity"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, output: str, task_description: str) -> Tuple[bool, Dict]:
        """Detects potential hallucinations in the output."""
        checks = {}

        # Check 1: Hallucination Detection (Placeholder - needs NLP model)
        checks["no_hallucinations"] = "hallucination" not in output.lower() # Simple keyword check

        passed = all(checks.values())
        reasoning = "Output deemed free of hallucinations." if passed else "Potential hallucinations detected."

        # Log decision
        await self._log_decision("gamma", passed, checks, task_description)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")

class GateDelta:
    """Gate Delta: Memory Integration"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, memory_key: str, expected_value: Any, task_description: str) -> Tuple[bool, Dict]:
        """Validates the correctness of memory storage operations."""
        checks = {}

        # Check 1: Value in Memory
        stored_value = self.memory.get_value(memory_key)
        checks["value_present"] = stored_value is not None

        # Check 2: Value Correctness
        checks["value_correct"] = stored_value == expected_value

        passed = all(checks.values())
        reasoning = "Memory integration successful." if passed else "Memory integration failed."

        # Log decision
        await self._log_decision("delta", passed, checks, task_description)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")

class GateEpsilon:
    """Gate Epsilon: Strategy Alignment"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, output: str, task_description: str, metadata: Dict) -> Tuple[bool, Dict]:
        """Ensures the output aligns with revenue generation strategies."""
        checks = {}

        # Check 1: Keyword Alignment (Example - needs revenue keyword list)
        revenue_keywords = metadata.get("revenue_keywords", [])
        output_keywords = re.findall(r'\b\w+\b', output.lower())
        checks["revenue_keywords_present"] = any(keyword in output_keywords for keyword in revenue_keywords)

        passed = all(checks.values())
        reasoning = "Output aligns with revenue strategy." if passed else "Output does not align with revenue strategy."

        # Log decision
        await self._log_decision("epsilon", passed, checks, task_description, metadata)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str, metadata: Dict):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "metadata": metadata,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")

class GateZeta:
    """Gate Zeta: Budget Compliance"""
    def __init__(self, memory_stores):
        self.memory = memory_stores

    async def validate(self, resource_usage: Dict, task_description: str, metadata: Dict) -> Tuple[bool, Dict]:
        """Monitors resource usage and ensures budget compliance."""
        checks = {}

        # Check 1: CPU Usage Limit (Example)
        checks["cpu_usage_within_limit"] = resource_usage.get("cpu", 0) < metadata.get("cpu_limit", 1.0)

        # Check 2: Memory Usage Limit (Example)
        checks["memory_usage_within_limit"] = resource_usage.get("memory", 0) < metadata.get("memory_limit", 1024)

        passed = all(checks.values())
        reasoning = "Resource usage within budget." if passed else "Resource usage exceeds budget."

        # Log decision
        await self._log_decision("zeta", passed, checks, task_description, metadata)

        return passed, {"checks": checks, "reasoning": reasoning}

    async def _log_decision(self, gate_name: str, passed: bool, checks: Dict, task_description: str, metadata: Dict):
        log_data = {
            "gate": gate_name,
            "passed": passed,
            "checks": checks,
            "task_description": task_description,
            "metadata": metadata,
            "timestamp": datetime.utcnow().isoformat()
        }
        try:
            self.memory.log_audit(f"gate_{gate_name}_validation", "system", log_data)
        except Exception as e:
            print(f"[WARNING] Audit logging failed for Gate {gate_name}: {e}")

# --- Orchestrator ---

class SixGateValidator:
    def __init__(self):
        self.memory = memory
        self.gate_alpha = GateAlpha(memory)
        self.gate_beta = GateBeta(memory)
        self.gate_gamma = GateGamma(memory)
        self.gate_delta = GateDelta(memory)
        self.gate_epsilon = GateEpsilon(memory)
        self.gate_zeta = GateZeta(memory)

    async def validate(self, input_data: str, output: str, memory_key: str, expected_value: Any, resource_usage: Dict, task_description: str, worker_id: str, metadata: Dict) -> Dict:
        """Orchestrates the six-gate validation process."""
        
        # Gate Alpha: Input Validity
        alpha_passed, alpha_report = await self.gate_alpha.validate(input_data, metadata, task_description)
        if not alpha_passed:
            return self._create_report(worker_id, False, "Gate Alpha failed", {"alpha": alpha_report})

        # Gate Beta: Output Quality
        beta_passed, beta_report = await self.gate_beta.validate(output, input_data, task_description)
        if not beta_passed:
            return self._create_report(worker_id, False, "Gate Beta failed", {"beta": beta_report})

        # Gate Gamma: Insight Purity
        gamma_passed, gamma_report = await self.gate_gamma.validate(output, task_description)
        if not gamma_passed:
            return self._create_report(worker_id, False, "Gate Gamma failed", {"gamma": gamma_report})

        # Gate Delta: Memory Integration
        delta_passed, delta_report = await self.gate_delta.validate(memory_key, expected_value, task_description)
        if not delta_passed:
            return self._create_report(worker_id, False, "Gate Delta failed", {"delta": delta_report})

        # Gate Epsilon: Strategy Alignment
        epsilon_passed, epsilon_report = await self.gate_epsilon.validate(output, task_description, metadata)
        if not epsilon_passed:
            return self._create_report(worker_id, False, "Gate Epsilon failed", {"epsilon": epsilon_report})

        # Gate Zeta: Budget Compliance
        zeta_passed, zeta_report = await self.gate_zeta.validate(resource_usage, task_description, metadata)
        if not zeta_passed:
            return self._create_report(worker_id, False, "Gate Zeta failed", {"zeta": zeta_report})

        # All gates passed
        overall_status = "All gates passed"
        passed = True
        gates_report = {
            "alpha": alpha_report,
            "beta": beta_report,
            "gamma": gamma_report,
            "delta": delta_report,
            "epsilon": epsilon_report,
            "zeta": zeta_report
        }

        report = self._create_report(worker_id, passed, overall_status, gates_report)

        # Log to immutable audit trail (Patent P4)
        try:
            self.memory.log_audit("six_gate_validation", worker_id, report)
        except Exception as e:
            print(f"[WARNING] Audit logging failed: {e}")
            
        # Update worker trust (Patent P9)
        try:
            self.memory.update_worker_trust(worker_id, passed)
        except Exception as e:
            print(f"[WARNING] Trust update failed: {e}")

        return report

    def _create_report(self, worker_id: str, passed: bool, status: str, gates: Dict) -> Dict:
        """Creates a standardized report."""
        return {
            "timestamp": datetime.utcnow().isoformat(),
            "worker_id": worker_id,
            "passed": passed,
            "status": status,
            "gates": gates
        }

# --- Example Usage ---

async def main():
    validator = SixGateValidator()

    # Example Data
    input_data = "This is a sample input for validation."
    output = "This is a sample output with relevant keywords."
    memory_key = "example_key"
    expected_value = "example_value"
    resource_usage = {"cpu": 0.5, "memory": 512}
    task_description = "Generate a summary of the input data."
    worker_id = "worker123"
    metadata = {
        "source_trust_score": 0.8,
        "revenue_keywords": ["sales", "profit", "revenue"],
        "cpu_limit": 0.7,
        "memory_limit": 700
    }

    # Run Validation
    report = await validator.validate(input_data, output, memory_key, expected_value, resource_usage, task_description, worker_id, metadata)
    print(report)

# --- Run Example ---
if __name__ == "__main__":
    asyncio.run(main())