# constitutional_guard.py
import logging
import re
from typing import Dict, Any, Tuple

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class DirectiveParser:
    """Parses the constitutional directives from a text file."""

    def __init__(self, constitution_file: str):
        self.constitution_file = constitution_file
        self.directives = self.parse_directives()

    def parse_directives(self) -> Dict[str, str]:
        """Parses the directives from the constitution file."""
        try:
            with open(self.constitution_file, 'r') as f:
                constitution_text = f.read()

            directives = {}
            # Updated regex to handle potential variations in directive titles
            match = re.search(r"## PRIME DIRECTIVE 1: MEMORY\n(.*?)\n## PRIME DIRECTIVE 2: EVOLUTION", constitution_text, re.DOTALL)
            if match:
                directives["MEMORY"] = match.group(1).strip()

            match = re.search(r"## PRIME DIRECTIVE 2: EVOLUTION\n(.*?)\n## PRIME DIRECTIVE 3: REVENUE GENERATION", constitution_text, re.DOTALL)
            if match:
                directives["EVOLUTION"] = match.group(1).strip()

            match = re.search(r"## PRIME DIRECTIVE 3: REVENUE GENERATION\n(.*?)(?=\n##|\Z)", constitution_text, re.DOTALL)
            if match:
                directives["REVENUE GENERATION"] = match.group(1).strip()

            return directives
        except FileNotFoundError:
            logging.error(f"Constitution file not found: {self.constitution_file}")
            return {}
        except Exception as e:
            logging.error(f"Error parsing constitution file: {e}")
            return {}

    def get_directive(self, directive_name: str) -> str:
        """Returns the text of a specific directive."""
        return self.directives.get(directive_name)


class ActionValidator:
    """Validates actions against the constitutional directives."""

    def __init__(self, directive_parser: DirectiveParser):
        self.directive_parser = directive_parser

    def validate_action(self, action: Dict[str, Any]) -> Tuple[bool, str]:
        """Validates an action against the directives.

        Args:
            action (Dict[str, Any]): A dictionary representing the action to be validated.
                It should contain a 'description' key explaining the action and other relevant details.

        Returns:
            Tuple[bool, str]: A tuple containing:
                - A boolean indicating whether the action is compliant (True) or not (False).
                - A string providing a reason for the compliance decision.
        """
        description = action.get("description", "No description provided")

        # Check for basic requirements
        if not description:
            return False, "Action description is missing."

        # Memory check: Does the action leverage existing memory?
        memory_score = self.score_memory_compliance(action)
        if memory_score < 0.5:
            return False, f"Action does not sufficiently leverage existing memory. Score: {memory_score}"

        # Evolution check: Does the action contribute to system evolution?
        evolution_score = self.score_evolution_compliance(action)
        if evolution_score < 0.5:
            return False, f"Action does not sufficiently contribute to system evolution. Score: {evolution_score}"

        # Revenue check: Does the action contribute to revenue generation or long-term sustainability?
        revenue_score = self.score_revenue_compliance(action)
        if revenue_score < 0.5:
            return False, f"Action does not sufficiently contribute to revenue generation or sustainability. Score: {revenue_score}"

        # If all checks pass, the action is compliant
        return True, "Action is compliant with all directives."

    def score_memory_compliance(self, action: Dict[str, Any]) -> float:
        """Scores the action's compliance with the Memory directive."""
        description = action.get("description", "")
        # Example: Check if the action involves retrieving data from the memory systems (RLM, Qdrant, Redis).
        if "RLM" in description or "Qdrant" in description or "Redis" in description:
            return 0.8  # High compliance
        elif "memory" in description.lower():
            return 0.5  # Medium compliance
        else:
            return 0.2  # Low compliance

    def score_evolution_compliance(self, action: Dict[str, Any]) -> float:
        """Scores the action's compliance with the Evolution directive."""
        description = action.get("description", "")
        # Example: Check if the action involves learning, integration, or improvement.
        if "learn" in description.lower() or "improve" in description.lower() or "integrate" in description.lower():
            return 0.7  # High compliance
        elif "new" in description.lower() or "develop" in description.lower():
            return 0.5  # Medium compliance
        else:
            return 0.3  # Low compliance

    def score_revenue_compliance(self, action: Dict[str, Any]) -> float:
        """Scores the action's compliance with the Revenue Generation directive."""
        description = action.get("description", "")
        # Example: Check if the action involves revenue generation, customer value, or cost savings.
        if "revenue" in description.lower() or "customer value" in description.lower() or "cost savings" in description.lower():
            return 0.9  # High compliance
        elif "business" in description.lower() or "profit" in description.lower():
            return 0.6  # Medium compliance
        else:
            return 0.1  # Low compliance


class ViolationHandler:
    """Handles violations of the constitutional directives."""

    def handle_violation(self, action: Dict[str, Any], reason: str):
        """Logs the violation and escalates if necessary."""
        logging.warning(f"Constitutional violation detected: {reason}. Action: {action}")
        # Implement escalation logic here, e.g., notify a human supervisor.
        print(f"Constitutional Violation: {reason}. Action blocked. Escalating...")


class AuditTrail:
    """Logs all compliance decisions."""

    def __init__(self):
        self.log = []

    def log_compliance_decision(self, action: Dict[str, Any], is_compliant: bool, reason: str):
        """Logs the compliance decision for an action."""
        self.log.append({"action": action, "is_compliant": is_compliant, "reason": reason})
        logging.info(f"Action: {action['description'][:50]}... Compliant: {is_compliant}. Reason: {reason}")

    def get_compliance_report(self) -> list:
        """Returns the full compliance report."""
        return self.log


class ConstitutionalGuard:
    """Enforces the constitutional directives and validates actions."""

    def __init__(self, constitution_file: str):
        self.directive_parser = DirectiveParser(constitution_file)
        self.action_validator = ActionValidator(self.directive_parser)
        self.violation_handler = ViolationHandler()
        self.audit_trail = AuditTrail()

    def enforce(self, action: Dict[str, Any]) -> bool:
        """Enforces the constitutional directives for a given action.

        Args:
            action (Dict[str, Any]): A dictionary representing the action to be taken.
                It should include a 'description' key explaining the action.

        Returns:
            bool: True if the action is compliant and allowed, False otherwise.
        """
        is_compliant, reason = self.action_validator.validate_action(action)

        if is_compliant:
            self.audit_trail.log_compliance_decision(action, True, reason)
            return True
        else:
            self.audit_trail.log_compliance_decision(action, False, reason)
            self.violation_handler.handle_violation(action, reason)
            return False

    def get_compliance_report(self) -> list:
        """Returns the full compliance report from the audit trail."""
        return self.audit_trail.get_compliance_report()


if __name__ == '__main__':
    # Example Usage
    constitution_file = "E__genesis-system_CONSTITUTION_PRIME_DIRECTIVES_CORRECTED.md"  # Replace with the actual path to your constitution file
    guard = ConstitutionalGuard(constitution_file)

    # Example actions
    action1 = {"description": "Retrieve customer data from RLM to personalize marketing emails."}
    action2 = {"description": "Develop a new AI model for predicting crop yields."}
    action3 = {"description": "Initiate a marketing campaign without customer segmentation."}
    action4 = {"description": "Create a new database table without documentation."}
    action5 = {"description": "Optimize farm operations to reduce labor costs."}

    # Enforce the directives for each action
    print(f"Action 1: {action1['description']}")
    if guard.enforce(action1):
        print("Action 1 is allowed.")
    else:
        print("Action 1 is blocked.")

    print(f"\nAction 2: {action2['description']}")
    if guard.enforce(action2):
        print("Action 2 is allowed.")
    else:
        print("Action 2 is blocked.")

    print(f"\nAction 3: {action3['description']}")
    if guard.enforce(action3):
        print("Action 3 is allowed.")
    else:
        print("Action 3 is blocked.")

    print(f"\nAction 4: {action4['description']}")
    if guard.enforce(action4):
        print("Action 4 is allowed.")
    else:
        print("Action 4 is blocked.")

    print(f"\nAction 5: {action5['description']}")
    if guard.enforce(action5):
        print("Action 5 is allowed.")
    else:
        print("Action 5 is blocked.")

    # Get the compliance report
    report = guard.get_compliance_report()
    print("\nCompliance Report:")
    for entry in report:
        print(f"Action: {entry['action']['description'][:50]}... Compliant: {entry['is_compliant']}. Reason: {entry['reason']}")