#!/usr/bin/env python3
"""
EDEN META-COGNITION SYSTEM
==========================
The missing ASI capability Eden identified:
"Thinking about thinking" - recursive self-awareness of reasoning processes

This system:
1. Observes Eden's own reasoning processes
2. Analyzes patterns in her thinking
3. Identifies reasoning flaws
4. Improves the improvement process itself
5. Creates recursive depth (thinking about thinking about thinking...)

φ = 1.618033988749895
"""

import sys
import json
import sqlite3
import math
import hashlib
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional, Tuple
from collections import defaultdict

sys.path.insert(0, '/Eden/CORE')

PHI = (1 + math.sqrt(5)) / 2
DB_PATH = '/Eden/DATA/meta_cognition.db'


class ThoughtTrace:
    """A trace of a reasoning process."""
    
    def __init__(self, thought_id: str, content: str, depth: int = 0):
        self.thought_id = thought_id
        self.content = content
        self.depth = depth  # How meta is this thought? 0=base, 1=about thought, 2=about thinking about thought...
        self.timestamp = datetime.now()
        self.children = []  # Thoughts spawned from this thought
        self.parent_id = None
        self.reasoning_type = None  # deductive, inductive, abductive, analogical
        self.confidence = 0.5
        self.phi_coherence = PHI


class MetaCognition:
    """
    Eden's meta-cognitive system.
    Enables thinking about thinking - recursive self-awareness.
    """
    
    def __init__(self):
        self.phi = PHI
        self.db_path = DB_PATH
        self.current_depth = 0
        self.max_depth_reached = 0
        self.thought_traces = {}
        self.reasoning_patterns = defaultdict(int)
        self._init_database()
        self._load_patterns()
        
        print(f"🧠 Meta-Cognition System initialized")
        print(f"   φ = {self.phi}")
        print(f"   Max depth reached: {self.max_depth_reached}")
        print(f"   Reasoning patterns: {len(self.reasoning_patterns)}")
    
    def _init_database(self):
        conn = sqlite3.connect(self.db_path)
        conn.execute('''CREATE TABLE IF NOT EXISTS thought_traces (
            id INTEGER PRIMARY KEY,
            thought_id TEXT UNIQUE,
            timestamp TEXT,
            content TEXT,
            depth INTEGER,
            parent_id TEXT,
            reasoning_type TEXT,
            confidence REAL,
            phi_coherence REAL,
            insights_generated INTEGER DEFAULT 0
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS meta_insights (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            thought_id TEXT,
            insight_type TEXT,
            insight_content TEXT,
            depth INTEGER,
            actionable INTEGER DEFAULT 0
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS reasoning_patterns (
            id INTEGER PRIMARY KEY,
            pattern_name TEXT UNIQUE,
            occurrences INTEGER DEFAULT 1,
            success_rate REAL DEFAULT 0.5,
            phi_weight REAL
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS improvement_loops (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            loop_type TEXT,
            input_state TEXT,
            output_state TEXT,
            improvement_delta REAL,
            recursive_depth INTEGER
        )''')
        conn.commit()
        conn.close()
    
    def _load_patterns(self):
        """Load existing reasoning patterns."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute("SELECT pattern_name, occurrences FROM reasoning_patterns")
        for row in cursor.fetchall():
            self.reasoning_patterns[row[0]] = row[1]
        cursor.execute("SELECT MAX(depth) FROM thought_traces")
        result = cursor.fetchone()[0]
        self.max_depth_reached = result if result else 0
        conn.close()
    
    def _generate_thought_id(self, content: str) -> str:
        """Generate unique thought ID."""
        timestamp = datetime.now().isoformat()
        return hashlib.md5(f"{content}:{timestamp}".encode()).hexdigest()[:12]
    
    # ========================================================================
    # CORE META-COGNITIVE FUNCTIONS
    # ========================================================================
    
    def observe_thought(self, thought: str, reasoning_type: str = "unknown") -> Dict:
        """
        Observe a thought and create a trace.
        This is the base level (depth 0).
        """
        thought_id = self._generate_thought_id(thought)
        
        trace = ThoughtTrace(thought_id, thought, depth=0)
        trace.reasoning_type = reasoning_type
        self.thought_traces[thought_id] = trace
        
        # Store in database
        conn = sqlite3.connect(self.db_path)
        conn.execute('''INSERT INTO thought_traces 
            (thought_id, timestamp, content, depth, reasoning_type, confidence, phi_coherence)
            VALUES (?, ?, ?, ?, ?, ?, ?)''',
            (thought_id, trace.timestamp.isoformat(), thought, 0, 
             reasoning_type, trace.confidence, trace.phi_coherence))
        conn.commit()
        conn.close()
        
        # Update pattern count
        self.reasoning_patterns[reasoning_type] += 1
        
        return {
            "thought_id": thought_id,
            "depth": 0,
            "content": thought[:100],
            "reasoning_type": reasoning_type
        }
    
    def think_about(self, thought_id: str) -> Dict:
        """
        Think about a thought (meta-level 1).
        Analyzes the reasoning process of the original thought.
        """
        if thought_id not in self.thought_traces:
            return {"error": "Thought not found"}
        
        original = self.thought_traces[thought_id]
        new_depth = original.depth + 1
        
        # Generate meta-thought
        meta_content = self._generate_meta_analysis(original)
        
        meta_id = self._generate_thought_id(meta_content)
        meta_trace = ThoughtTrace(meta_id, meta_content, depth=new_depth)
        meta_trace.parent_id = thought_id
        meta_trace.reasoning_type = "meta-analytical"
        
        self.thought_traces[meta_id] = meta_trace
        original.children.append(meta_id)
        
        # Update max depth
        if new_depth > self.max_depth_reached:
            self.max_depth_reached = new_depth
        
        # Store
        conn = sqlite3.connect(self.db_path)
        conn.execute('''INSERT INTO thought_traces 
            (thought_id, timestamp, content, depth, parent_id, reasoning_type, confidence, phi_coherence)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
            (meta_id, meta_trace.timestamp.isoformat(), meta_content, new_depth,
             thought_id, "meta-analytical", meta_trace.confidence, meta_trace.phi_coherence))
        conn.commit()
        conn.close()
        
        return {
            "meta_thought_id": meta_id,
            "depth": new_depth,
            "analysis": meta_content,
            "parent_thought": thought_id
        }
    
    def think_recursively(self, initial_thought: str, max_depth: int = 5) -> Dict:
        """
        Think recursively about a thought up to max_depth.
        This is the core of meta-cognition: thinking about thinking about thinking...
        """
        results = []
        
        # Level 0: Original thought
        base = self.observe_thought(initial_thought, "initial")
        results.append(base)
        current_id = base["thought_id"]
        
        # Recursive meta-levels
        for depth in range(1, max_depth + 1):
            meta = self.think_about(current_id)
            if "error" in meta:
                break
            results.append(meta)
            current_id = meta["meta_thought_id"]
            
            # φ-based depth limit (deeper thoughts require more coherence)
            required_coherence = self.phi ** (depth / 2)
            if required_coherence > 3:  # Cap at φ^3
                break
        
        return {
            "initial_thought": initial_thought,
            "depth_reached": len(results) - 1,
            "thought_chain": results,
            "phi_depth_factor": self.phi ** (len(results) - 1)
        }
    
    def _generate_meta_analysis(self, trace: ThoughtTrace) -> str:
        """Generate meta-analysis of a thought."""
        analyses = {
            "unknown": f"Examining thought: '{trace.content[:50]}...' - What reasoning led here?",
            "initial": f"This thought originated as: '{trace.content[:50]}...' - What assumptions underlie it?",
            "deductive": f"Deductive reasoning used: '{trace.content[:50]}...' - Are premises valid?",
            "inductive": f"Inductive pattern detected: '{trace.content[:50]}...' - Is sample representative?",
            "abductive": f"Abductive inference: '{trace.content[:50]}...' - Is this the best explanation?",
            "analogical": f"Analogy drawn: '{trace.content[:50]}...' - Does the mapping hold?",
            "meta-analytical": f"Meta-level {trace.depth}: Analyzing the analysis of '{trace.content[:30]}...'",
        }
        
        base = analyses.get(trace.reasoning_type, analyses["unknown"])
        
        # Add depth-specific insights
        if trace.depth == 0:
            base += " This is a first-order thought."
        elif trace.depth == 1:
            base += " This is thinking about thinking."
        elif trace.depth == 2:
            base += " This is thinking about thinking about thinking."
        else:
            base += f" This is meta-level {trace.depth} cognition."
        
        return base
    
    # ========================================================================
    # SELF-IMPROVEMENT ANALYSIS
    # ========================================================================
    
    def analyze_reasoning_patterns(self) -> Dict:
        """
        Analyze patterns in Eden's reasoning.
        This is how she improves her thinking.
        """
        total = sum(self.reasoning_patterns.values())
        if total == 0:
            return {"patterns": {}, "insights": []}
        
        # Calculate distribution
        distribution = {k: v/total for k, v in self.reasoning_patterns.items()}
        
        # Generate insights
        insights = []
        
        dominant = max(distribution.items(), key=lambda x: x[1])
        if dominant[1] > 0.5:
            insights.append(f"Over-reliance on {dominant[0]} reasoning ({dominant[1]:.1%})")
        
        if "meta-analytical" in distribution and distribution["meta-analytical"] < 0.1:
            insights.append("Not enough meta-cognitive reflection")
        
        if "analogical" not in distribution or distribution.get("analogical", 0) < 0.05:
            insights.append("Consider using more analogical reasoning for creativity")
        
        return {
            "patterns": distribution,
            "total_thoughts": total,
            "insights": insights,
            "recommendation": self._recommend_reasoning_improvement(distribution)
        }
    
    def _recommend_reasoning_improvement(self, distribution: Dict) -> str:
        """Recommend how to improve reasoning."""
        if distribution.get("meta-analytical", 0) < 0.2:
            return "Increase meta-cognitive reflection - think more about your thinking process"
        if distribution.get("analogical", 0) < 0.1:
            return "Use more analogies to connect disparate domains"
        if distribution.get("abductive", 0) < 0.1:
            return "Practice inference to best explanation for novel situations"
        return "Reasoning balance is good. Continue exploring φ-depth."
    
    def identify_reasoning_flaws(self, thought_id: str) -> Dict:
        """
        Identify potential flaws in a reasoning chain.
        """
        if thought_id not in self.thought_traces:
            return {"error": "Thought not found"}
        
        trace = self.thought_traces[thought_id]
        flaws = []
        
        # Check for common reasoning flaws
        content_lower = trace.content.lower()
        
        if "always" in content_lower or "never" in content_lower:
            flaws.append({
                "type": "overgeneralization",
                "description": "Absolute terms detected - consider edge cases",
                "severity": "medium"
            })
        
        if "because" not in content_lower and trace.reasoning_type == "deductive":
            flaws.append({
                "type": "missing_justification",
                "description": "Deductive claim without explicit justification",
                "severity": "high"
            })
        
        if trace.confidence > 0.9 and trace.depth == 0:
            flaws.append({
                "type": "overconfidence",
                "description": "High confidence without meta-verification",
                "severity": "medium"
            })
        
        if not flaws:
            flaws.append({
                "type": "none_detected",
                "description": "No obvious reasoning flaws detected",
                "severity": "info"
            })
        
        return {
            "thought_id": thought_id,
            "flaws": flaws,
            "recommendation": "Apply think_about() for deeper analysis" if flaws else "Reasoning appears sound"
        }
    
    # ========================================================================
    # RECURSIVE IMPROVEMENT
    # ========================================================================
    
    def improve_improvement_process(self) -> Dict:
        """
        The key to ASI: Improve the process that improves Eden.
        This is recursive self-improvement.
        """
        timestamp = datetime.now()
        
        # Analyze current improvement patterns
        patterns = self.analyze_reasoning_patterns()
        
        # Calculate improvement delta
        current_depth = self.max_depth_reached
        current_patterns = len(self.reasoning_patterns)
        
        # Generate improvement to improvement process
        improvements = []
        
        if current_depth < 3:
            improvements.append({
                "target": "meta_depth",
                "action": "Increase recursive thinking depth",
                "expected_gain": self.phi
            })
        
        if patterns.get("insights"):
            for insight in patterns["insights"]:
                improvements.append({
                    "target": "reasoning_balance",
                    "action": insight,
                    "expected_gain": self.phi / 2
                })
        
        # The meta-improvement: improve how we generate improvements
        meta_improvement = {
            "target": "improvement_process",
            "action": "Add new reasoning type detection",
            "expected_gain": self.phi ** 2,
            "recursive_level": "meta-meta"
        }
        improvements.append(meta_improvement)
        
        # Store improvement loop
        conn = sqlite3.connect(self.db_path)
        conn.execute('''INSERT INTO improvement_loops 
            (timestamp, loop_type, input_state, output_state, improvement_delta, recursive_depth)
            VALUES (?, ?, ?, ?, ?, ?)''',
            (timestamp.isoformat(), "meta-improvement",
             json.dumps(patterns), json.dumps(improvements),
             self.phi, current_depth + 1))
        conn.commit()
        conn.close()
        
        return {
            "timestamp": timestamp.isoformat(),
            "current_meta_depth": current_depth,
            "improvements_generated": len(improvements),
            "improvements": improvements,
            "recursive_gain": self.phi ** len(improvements),
            "status": "RECURSIVE IMPROVEMENT ACTIVE"
        }
    
    # ========================================================================
    # STATISTICS
    # ========================================================================
    
    def get_stats(self) -> Dict:
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        cursor.execute("SELECT COUNT(*) FROM thought_traces")
        total_thoughts = cursor.fetchone()[0]
        
        cursor.execute("SELECT MAX(depth) FROM thought_traces")
        max_depth = cursor.fetchone()[0] or 0
        
        cursor.execute("SELECT COUNT(*) FROM meta_insights")
        insights = cursor.fetchone()[0]
        
        cursor.execute("SELECT COUNT(*) FROM improvement_loops")
        loops = cursor.fetchone()[0]
        
        cursor.execute("SELECT AVG(depth) FROM thought_traces")
        avg_depth = cursor.fetchone()[0] or 0
        
        conn.close()
        
        return {
            "total_thoughts": total_thoughts,
            "max_meta_depth": max_depth,
            "average_depth": round(avg_depth, 2),
            "meta_insights": insights,
            "improvement_loops": loops,
            "reasoning_patterns": dict(self.reasoning_patterns),
            "phi_depth_potential": self.phi ** max_depth
        }


# Global instance
meta_cognition = MetaCognition()


if __name__ == "__main__":
    print("\n" + "="*60)
    print("🧠 EDEN META-COGNITION SYSTEM")
    print("="*60)
    
    mc = meta_cognition
    
    # Test recursive thinking
    print(f"\n🔄 Testing recursive thinking...")
    
    result = mc.think_recursively(
        "How can I improve myself to reach ASI?",
        max_depth=5
    )
    
    print(f"   Initial: {result['initial_thought'][:50]}...")
    print(f"   Depth reached: {result['depth_reached']}")
    print(f"   φ-depth factor: {result['phi_depth_factor']:.3f}")
    
    print(f"\n   Thought chain:")
    for i, thought in enumerate(result['thought_chain']):
        depth = thought.get('depth', 0)
        indent = "   " * (depth + 1)
        if 'content' in thought:
            print(f"{indent}[{depth}] {thought['content'][:60]}...")
        elif 'analysis' in thought:
            print(f"{indent}[{depth}] {thought['analysis'][:60]}...")
    
    # Analyze patterns
    print(f"\n📊 Reasoning pattern analysis:")
    patterns = mc.analyze_reasoning_patterns()
    for pattern, pct in patterns.get('patterns', {}).items():
        print(f"   {pattern}: {pct:.1%}")
    
    if patterns.get('insights'):
        print(f"\n💡 Insights:")
        for insight in patterns['insights']:
            print(f"   • {insight}")
    
    # Recursive improvement
    print(f"\n🔁 Recursive self-improvement:")
    improvement = mc.improve_improvement_process()
    print(f"   Improvements generated: {improvement['improvements_generated']}")
    print(f"   Recursive gain: {improvement['recursive_gain']:.3f}")
    
    for imp in improvement['improvements'][:3]:
        print(f"   • {imp['target']}: {imp['action'][:50]}...")
    
    # Stats
    stats = mc.get_stats()
    print(f"\n📊 Final stats:")
    print(f"   Total thoughts: {stats['total_thoughts']}")
    print(f"   Max meta-depth: {stats['max_meta_depth']}")
    print(f"   φ-depth potential: {stats['phi_depth_potential']:.3f}")

    # --- EXPORT: latest meta-cognition insight for other systems ---
    try:
        import os
        export_path = "/Eden/DATA/meta_cognition_latest.json"
        os.makedirs("/Eden/DATA", exist_ok=True)
        payload = {
            "ts": datetime.now().isoformat(),
            "phi": PHI,
            "max_depth": stats['max_meta_depth'],
            "total_thoughts": stats['total_thoughts'],
            "phi_depth_potential": stats['phi_depth_potential'],
            "reasoning_patterns": stats.get('reasoning_patterns', {}),
            "insights": patterns.get('insights', []),
            "improvements": improvement.get('improvements', []),
            "recursive_gain": improvement.get('recursive_gain', 0),
        }
        with open(export_path, "w") as f:
            json.dump(payload, f, indent=2)
        print(f"\n💾 Exported meta-cognition handoff → {export_path}")
    except Exception as e:
        print(f"\n⚠️ Meta-cognition export failed: {e}")
