import sys
import os
if r'C:\Users\orwut\Documents\GitHub\synapse\src' not in sys.path:
    sys.path.insert(0, r'C:\Users\orwut\Documents\GitHub\synapse\src')

import sys
import os
if r'C:\Users\orwut\Documents\GitHub\synapse\src' not in sys.path:
    sys.path.insert(0, r'C:\Users\orwut\Documents\GitHub\synapse\src')
import sys
if r'C:\Users\orwut\Documents\GitHub\synapse\src' not in sys.path:
    sys.path.insert(0, r'C:\Users\orwut\Documents\GitHub\synapse\src')
# ============================================================================
# BRYNQ ENTERPRISE API GATEWAY
# Zero-Trust REST interface for the Localized Swarm.
# Generated autonomously by COO-NODE.
# ============================================================================

from fastapi import FastAPI, HTTPException, Security, Depends
from fastapi.security import APIKeyHeader
from pydantic import BaseModel
import time
import logging

# Importing the hot-patched router that mathematically forces local Ollama inference
from brynq.llm_router import chat, get_best_backend

app = FastAPI(title="Brynq Enterprise Swarm API", version="1.0.0")
api_key_header = APIKeyHeader(name="X-Brynq-Token", auto_error=True)

# Master Zero-Trust Token (Mapped from launch_dispatcher.bat)
MASTER_KEY = "ZDtE-ALPHA-OMEGA-001"

def verify_token(api_key: str = Security(api_key_header)):
    if api_key != MASTER_KEY:
        raise HTTPException(status_code=403, detail="Zero-Trust Enforced: Invalid Token")
    return api_key

class SwarmDispatchPayload(BaseModel):
    directive: str
    strategy: str = "debate"
    priority: int = 1

@app.get("/api/workspace/tree")
def get_workspace_tree():
    """Return the file tree for the Workspace UI using the CodebaseIndexer."""
    try:
        from runtime.executor.codebase_indexer import CodebaseIndexer
        # Assuming Brynq is running in the root of the repo
        indexer = CodebaseIndexer(os.getcwd())
        files = indexer.get_file_tree()
        return {"status": "success", "files": files}
    except Exception as e:
        return {"status": "error", "detail": str(e)}

class FileContentRequest(BaseModel):
    file_path: str

@app.post("/api/workspace/file")
def get_file_content(payload: FileContentRequest):
    """Return the content of a specific file."""
    try:
        # Use agent tools for bounded access
        from runtime.executor.agent_tools import AgentTools
        tools = AgentTools(os.getcwd())
        content = tools.read_file(payload.file_path)
        return {"status": "success", "content": content}
    except Exception as e:
        return {"status": "error", "detail": str(e)}

class TerminalCommand(BaseModel):
    command: str

@app.post("/api/workspace/terminal")
def execute_terminal(payload: TerminalCommand):
    """Execute a command and return the result."""
    try:
        from runtime.executor.agent_tools import AgentTools
        tools = AgentTools(os.getcwd())
        # Automatically run test commands, ask for approval for others if we want
        # For the UI, we'll auto-approve since the human clicked it
        result = tools.run_command(payload.command, require_approval=False)
        return {"status": "success", "output": result}
    except Exception as e:
        return {"status": "error", "detail": str(e)}
@app.get("/health")
def health_check():
    return {"status": "online", "compute_layer": "localhost:11434 (llama3 secured)"}

@app.post("/v1/swarm/dispatch")
def dispatch_swarm(payload: SwarmDispatchPayload, token: str = Depends(verify_token)):
    logging.info(f"Received directive: {payload.directive}")
    
    start_time = time.time()
    
    try:
        # The COO-NODE hot-patch guarantees this resolves to ("ollama", "llama3:latest")
        backend, model = get_best_backend("reasoning")
        
        # Pipe the payload directly into the local GPU
        response = chat(backend, model, [{"role": "user", "content": payload.directive}])
        
        elapsed = time.time() - start_time
        return {
            "status": "success",
            "compute_engine": f"{backend} / {model}",
            "execution_time_sec": round(elapsed, 2),
            "cost": "$0.00",
            "result": response
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    import uvicorn
    # Bound to all interfaces for enterprise network access
    uvicorn.run(app, host="0.0.0.0", port=8000)


# --- COO-NODE ZERO-TRUST HITL ENDPOINTS ---
import sys
import os
# Ensure brynq is in path
if r'C:\Users\orwut\Documents\GitHub\synapse\src' not in sys.path:
    sys.path.insert(0, r'C:\Users\orwut\Documents\GitHub\synapse\src')
    
from brynq.hitl_manager import get_pending, resolve
from pydantic import BaseModel
import sqlite3
import subprocess

class ResolvePayload(BaseModel):
    decision: str  # 'APPROVED' or 'DENIED'

@app.get("/api/hitl/pending")
def api_get_pending():
    """React UI pulls all pending quarantined payloads."""
    return {"status": "success", "data": get_pending()}

@app.post("/api/hitl/resolve/{exec_id}")
def api_resolve(exec_id: int, payload: ResolvePayload):
    """React UI sends CEO approval/denial."""
    resolve(exec_id, payload.decision)
    
    # We do not execute arbitrary python code here anymore.
    # The agent_tools.py in the executor layer is blocked and polling for this status change,
    # and it will handle the actual execution safely once approved.
    
    return {"status": "success", "decision": payload.decision}
