"""
BloomOS v0 Runtime - FastAPI Service

Front-door task router that uses Helix64 Position 4 gates to steer
multi-objective optimization based on task type.

Architecture:
    POST /task → [Resolve anchors + gate] → [Modify program at pos 4]
              → [Call Helix64 backend] → [Format output + receipt]
"""

import os
import json
import requests
from typing import Dict, Any
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse

from helix_cdc.bloomos.schemas import TaskRequest, TaskResult
from helix_cdc.bloomos.bridge import get_bloomos_status
from helix_cdc.bloomos.backplane import DEFAULT_BACKPLANE
from helix_cdc.bloomos.receipts import generate_task_id, generate_receipt

# Configuration
HELIX64_BACKEND = os.getenv("HELIX64_BACKEND", "http://localhost:5065/execute")
BASE_PROGRAM = os.getenv("BASE_PROGRAM", "ABCDEFGH")  # Default program (E at position 4)
BLOOMOS_PORT = int(os.getenv("BLOOMOS_PORT", "7070"))

app = FastAPI(
    title="BloomOS v0 Runtime",
    description="Task router with Helix64 Position 4 anchor-sensitive gates",
    version="0.1.0"
)


@app.get("/")
def root():
    """Health check endpoint"""
    return {
        "service": "BloomOS v0 Runtime",
        "version": "0.1.0",
        "status": "ok",
        "helix64_backend": HELIX64_BACKEND,
        "base_program": BASE_PROGRAM
    }


@app.get("/status")
def status():
    """Get BloomOS integration status"""
    return get_bloomos_status()


@app.get("/gates")
def list_gates():
    """List available gate policies"""
    from helix_cdc.bloomos.gates import GATE_POLICIES
    return {"gate_policies": GATE_POLICIES}


@app.post("/task", response_model=TaskResult)
def execute_task(request: TaskRequest) -> TaskResult:
    """
    Execute a task through Helix64 with position 4 gate selection.

    Flow:
        1. Resolve anchors (from task_type or override)
        2. Choose gate policy (from task_type or override)
        3. Apply gate to base program (mutate position 4)
        4. Execute on Helix64 backend for each anchor
        5. Format output and generate receipt

    Args:
        request: TaskRequest with task_type, description, anchors, gate_policy

    Returns:
        TaskResult with output, gate info, logits, and receipt
    """
    # Generate task ID
    task_id = generate_task_id(request.model_dump())

    try:
        # Execute task via backplane (FlowTorch-style braiding)
        bp_result = DEFAULT_BACKPLANE.run_task(
            task_type=request.task_type,
            description=request.description,
            anchors=request.anchors,
            gate_policy=request.gate_policy,
            base_program=BASE_PROGRAM,
            helix_program=request.helix_program,
        )

        # Check if execution succeeded
        backend_results = bp_result["backend_results"]
        success_count = sum(1 for r in backend_results.values() if r.get("status") == "ok")

        if success_count == 0:
            # All anchors failed
            error_msg = "; ".join([
                f"{a}: {r.get('error', 'unknown')}"
                for a, r in backend_results.items()
            ])
            result = TaskResult(
                task_id=task_id,
                status="error",
                output=None,
                gate_used=bp_result["gate"]["policy"],
                helix_program_used=bp_result["gate"]["program_after"],
                anchors_used=bp_result["anchors_resolved"],
                error=f"All anchors failed: {error_msg}"
            )
            return result

        # Format output
        output = {
            "task_type": bp_result["task_type"],
            "description": bp_result["description"],
            "anchors": backend_results,
            "gate_effects": bp_result["gate"]["expected_effects"],
            "modified_program": bp_result["gate"]["program_after"],
            "bloomos_mode": bp_result["meta"]["backend"]
        }

        result_dict = {
            "task_id": task_id,
            "status": "ok",
            "output": output,
            "gate_used": bp_result["gate"]["policy"],
            "helix_program_used": bp_result["gate"]["program_after"],
            "anchors_used": bp_result["anchors_resolved"],
            "logits_mean": bp_result["logits_mean"],
            "logits_std": bp_result["logits_std"]
        }

        # Generate receipt
        receipt = generate_receipt(task_id, request.model_dump(), result_dict)
        result_dict["receipt"] = receipt

        result = TaskResult(**result_dict)
        return result

    except Exception as e:
        # Unexpected error
        result = TaskResult(
            task_id=task_id,
            status="error",
            output=None,
            gate_used="unknown",
            helix_program_used=None,
            anchors_used=[],
            error=f"Runtime error: {str(e)}"
        )
        return result


def main():
    """Run BloomOS runtime server"""
    import uvicorn
    print(f"🌸 Starting BloomOS v0 Runtime on port {BLOOMOS_PORT}")
    print(f"   Helix64 backend: {HELIX64_BACKEND}")
    print(f"   Base program: {BASE_PROGRAM}")
    uvicorn.run(app, host="0.0.0.0", port=BLOOMOS_PORT, log_level="info")


if __name__ == "__main__":
    main()
