from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn, math, subprocess
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
NODES = {"N1":[0,0,0],"N2":[10,0,0],"N3":[0,10,0],"N4":[10,10,0],"N5":[3,3,4],"N6":[7,3,4],"N7":[3,7,4],"N8":[7,7,4]}
VECTORS = [("V1","N1","N2"),("V2","N3","N4"),("V3","N1","N3"),("V4","N2","N4"),("V5","N5","N6"),("V6","N7","N8"),("V7","N5","N7"),("V8","N6","N8"),("V9","N1","N5"),("V10","N2","N6"),("V11","N3","N7"),("V12","N4","N8"),("V13","N1","N8")]
def vlen(a,b): return math.sqrt(sum((b[i]-a[i])**2 for i in range(3)))
def ice_route(text):
    vals=[float(ord(c)) for c in text[:3].ljust(3)]
    omegas=[]
    lam=4
    for v in vals:
        tau=int(abs(v))%9
        tau=1 if tau==0 else tau
        if tau%3==0: omega=(3*tau+lam)%9
        elif tau%3==1: omega=tau%9
        else: omega=(2*tau-lam)%9
        omegas.append(omega)
    s_n=omegas[0]*81+omegas[1]*9+omegas[2]
    return s_n,omegas
@app.get("/")
def root(): return {"system":"D.R. ONE","engine":"S.P.I.R.I.T.","status":"COHERENT","vectors":13,"nodes":8}
@app.get("/api/nodes")
def nodes(): return NODES
@app.get("/api/vectors")
def vectors():
    result=[]
    for v,a,b in VECTORS:
        na,nb=NODES[a],NODES[b]
        result.append({"id":v,"from":a,"to":b,"length":round(vlen(na,nb),4)})
    return result
@app.get("/api/coherence/metric")
def coherence():
    v1=vlen(NODES["N1"],NODES["N2"])
    v13=vlen(NODES["N1"],NODES["N8"])
    C=abs(v13/v1-math.sqrt(114)/10)
    return {"C":round(C,6),"status":"PASS" if C<=0.05 else "RESET","v1":v1,"v13":round(v13,4)}
@app.post("/api/ollama")
def ollama(data:dict):
    prompt=data.get("prompt","hello")
    s_n,omegas=ice_route(prompt)
    try:
        r=subprocess.run(["ollama","run","llama3.2"],input=f"[ICE STATE {s_n}]: {prompt}",capture_output=True,text=True,timeout=60)
        response=r.stdout.strip() or r.stderr.strip()
    except FileNotFoundError: response="Ollama not found"
    except Exception as e: response=f"Error: {str(e)}"
    return {"state":s_n,"omegas":omegas,"response":response}
if __name__=="__main__": uvicorn.run(app,host="0.0.0.0",port=8000)
