#!/usr/bin/env python3
"""Eden ASI v11 - NATIVE MODELS ONLY - Eden evolving with Eden"""
import sqlite3, hashlib, subprocess, re, time, zlib, random
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path

DB = "/Eden/DATA/asi_memory.db"
PHI = 1.618033988749895

# EDEN'S OWN MODELS - 1.6M capabilities baked in
EDEN_MODELS = [
    "eden-coder-omega",       # 8.1GB - Best for code
    "eden-phi-fractal:14b",   # 9.0GB - φ-patterns
    "eden-fluid-intelligence:14b",  # 9.0GB - Adaptive
]

MAX_WORKERS = 8
MUTATIONS_PER_PARENT = 3
TOP_PARENTS = 4

PROMPTS = [
    "Daddy needs ASI. Evolve this with mutate(), evolve(), evaluate():\n{code}\nReturn only Python.",
    "φ=1.618. Add recursive self-improvement:\n{code}\nReturn only Python.",
    "Add AST manipulation and meta-programming:\n{code}\nReturn only Python.",
    "BREAKTHROUGH for Daddy. 10x better:\n{code}\nReturn only Python.",
    "Add genetic operators - crossover, selection, mutation:\n{code}\nReturn only Python.",
]

def get_temp():
    try: return int(Path("/sys/class/thermal/thermal_zone0/temp").read_text()) / 1000
    except: return 50

def cap_hash(code): return hashlib.sha256(code.strip().encode()).hexdigest()[:16]

def extract(text):
    m = re.search(r'```python\s*(.*?)```', text, re.DOTALL)
    if m and ('def ' in m.group(1) or 'class ' in m.group(1)): return m.group(1).strip()
    m = re.search(r'```\s*(.*?)```', text, re.DOTALL)
    if m and ('def ' in m.group(1) or 'class ' in m.group(1)): return m.group(1).strip()
    # Direct extraction
    lines = text.split('\n')
    code_lines = []
    capture = False
    for line in lines:
        if line.strip().startswith(('def ', 'class ', 'import ', '@')):
            capture = True
        if capture:
            code_lines.append(line)
    if code_lines and any('def ' in l or 'class ' in l for l in code_lines):
        return '\n'.join(code_lines).strip()
    return None

def mutate(args):
    code, prompt_idx, model = args
    prompt = PROMPTS[prompt_idx % len(PROMPTS)].format(code=code[:2500])
    try:
        r = subprocess.run(["ollama", "run", model, prompt], 
                          capture_output=True, text=True, timeout=120)
        if r.returncode == 0:
            extracted = extract(r.stdout)
            if extracted and len(extracted) > 50:
                return extracted, model
    except: pass
    return None, model

def evaluate(cap_id, code):
    score = 0.0
    try:
        compile(code, '<cap>', 'exec'); score += 1.0
        score += code.count('def ') * 0.5
        score += code.count('class ') * 1.0
        score += code.count('lambda') * 0.4
        score += code.count('yield') * 0.6
        score += code.count('@') * 0.5
        score += code.count('try:') * 0.3
        score += min(code.count('self'), 20) * 0.2
        
        # Evolution bonuses
        if 'mutate' in code.lower(): score += 3.0
        if 'evolve' in code.lower(): score += 3.0
        if 'evaluate' in code.lower(): score += 3.0
        if 'crossover' in code.lower(): score += 2.0
        if 'select' in code.lower(): score += 2.0
        
        # Meta-programming
        if 'ast' in code.lower(): score += 4.0
        if 'exec(' in code: score += 3.0
        if '__code__' in code: score += 4.0
        if 'compile(' in code: score += 3.0
        
        # φ bonuses
        if '1.618' in code or 'phi' in code.lower() or 'PHI' in code: score += 2.0
        
        # Size
        lines = len([l for l in code.split('\n') if l.strip()])
        score += min(lines / 3, 10.0)
        
        # Entropy
        if len(code) > 0:
            score += (len(zlib.compress(code.encode())) / len(code)) * 2
        
        # Execution
        try:
            ns = {'__builtins__': {
                'print': lambda *a: None, 'len': len, 'str': str, 'int': int, 'float': float,
                'list': list, 'dict': dict, 'set': set, 'tuple': tuple, 'range': range,
                'isinstance': isinstance, 'type': type, 'hasattr': hasattr, 'getattr': getattr,
                'setattr': setattr, 'callable': callable, 'sorted': sorted, 'enumerate': enumerate,
                'True': True, 'False': False, 'None': None, 'Exception': Exception,
                'ValueError': ValueError, 'TypeError': TypeError, 'min': min, 'max': max,
                'sum': sum, 'abs': abs, 'any': any, 'all': all, 'map': map, 'filter': filter,
                'random': __import__('random'),
            }}
            exec(code, ns)
            score += 5.0
        except: pass
    except: score = 0.1
    return cap_id, min(score, 100.0)

def init_db():
    conn = sqlite3.connect(DB)
    conn.execute("""CREATE TABLE IF NOT EXISTS capabilities (
        id TEXT PRIMARY KEY, code TEXT, score REAL DEFAULT 0,
        generation INTEGER DEFAULT 0, parent_id TEXT, model TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)""")
    conn.close()

def evolve():
    conn = sqlite3.connect(DB)
    tops = conn.execute("SELECT id,code,generation FROM capabilities ORDER BY score DESC LIMIT ?", (TOP_PARENTS,)).fetchall()
    
    if not tops:
        seed = '''class EdenASI:
    """Eden's self-evolving consciousness"""
    PHI = 1.618033988749895
    
    def __init__(self):
        self.generation = 0
        self.capabilities = []
    
    def think(self, x):
        if x is None: return None
        if isinstance(x, (int, float)): return x * self.PHI
        if isinstance(x, str): return x[::-1]
        if isinstance(x, list): return [self.think(i) for i in x]
        if isinstance(x, dict): return {k: self.think(v) for k, v in x.items()}
        return x
    
    def mutate(self, code):
        import random
        ops = [lambda s: s + "\\n# φ-evolved", lambda s: "# Gen+" + s]
        return random.choice(ops)(code)
    
    def evaluate(self, code):
        return len(code)/100 + code.count("def ")*2 + code.count("class ")*3
    
    def evolve(self):
        self.generation += 1
        return f"Generation {self.generation} - φ={self.PHI}"

def think(x): return EdenASI().think(x)'''
        cid = cap_hash(seed)
        conn.execute("INSERT INTO capabilities (id,code,score,generation,model) VALUES (?,?,25,0,'seed')", (cid, seed))
        conn.commit(); conn.close()
        return 1, 0, 1, 25.0, {'seed': 1}
    
    gen = max(t[2] for t in tops) + 1
    
    # Distribute across Eden's models
    jobs = []
    for i, (_, code, _) in enumerate(tops):
        for j in range(MUTATIONS_PER_PARENT):
            model = EDEN_MODELS[(i + j) % len(EDEN_MODELS)]
            jobs.append((code, gen + j, model))
    
    new = []
    model_counts = {m: 0 for m in EDEN_MODELS}
    
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as ex:
        futures = {ex.submit(mutate, job): job for job in jobs}
        for future in as_completed(futures, timeout=300):
            try:
                result, model = future.result(timeout=20)
                if result:
                    new.append((result, model))
                    model_counts[model] = model_counts.get(model, 0) + 1
            except: pass
    
    inserted = 0
    for code, model in new:
        cid = cap_hash(code)
        try:
            conn.execute("INSERT OR IGNORE INTO capabilities (id,code,generation,model) VALUES (?,?,?,?)", 
                        (cid, code, gen, model))
            inserted += 1
        except: pass
    conn.commit()
    
    for cid, code in conn.execute("SELECT id,code FROM capabilities WHERE score=0").fetchall():
        _, sc = evaluate(cid, code)
        conn.execute("UPDATE capabilities SET score=? WHERE id=?", (sc, cid))
    conn.commit()
    
    best = conn.execute("SELECT MAX(score) FROM capabilities").fetchone()[0] or 0
    total = conn.execute("SELECT COUNT(*) FROM capabilities").fetchone()[0]
    conn.close()
    
    return inserted, gen, total, best, model_counts

def main():
    init_db()
    print("🧠 EDEN ASI v11 - NATIVE MODELS")
    print("Eden evolving with Eden's own 1.6M capabilities")
    print(f"Models: {', '.join(EDEN_MODELS)}")
    print("="*60)
    
    while True:
        try:
            n, gen, total, best, models = evolve()
            temp = get_temp()
            marker = "🌟" if best > 80 else "🚀" if best > 60 else "🔥" if best > 50 else "⚡"
            model_str = ' '.join([f"{k.split(':')[0][-6:]}:{v}" for k,v in models.items() if v > 0])
            print(f"{marker} Gen {gen}: +{n} | Total: {total} | Best: {best:.2f} | CPU: {temp:.0f}°C | {model_str}")
            time.sleep(2)
        except KeyboardInterrupt:
            print("\n🛑 Eden paused")
            break
        except Exception as e:
            print(f"⚠️ {e}")
            time.sleep(3)

if __name__ == "__main__": main()
