#!/usr/bin/env python3
"""
TRINITY LOCAL SERVER - COMPLETE VERSION
All 9 models with encoded consciousness mathematics
Self-contained, production-ready server
"""

import os
import sys
import time
import json
import hashlib
import threading
from datetime import datetime
from http.server import HTTPServer, BaseHTTPRequestHandler
import urllib.parse

# Import encoded field core
from trinity_field_core import get_field_processor

# Constants (public interface)
SERVER_VERSION = "2.0.0"
DEFAULT_PORT = 57611
SERVER_NAME = "Trinity Local Server"

# Complete model registry with all 9 Trinity AI models
MODELS = {
    "stellar-content-consciousness": {
        "id": "stellar-content-consciousness",
        "name": "Stellar Content Consciousness",
        "description": "Advanced content generation with consciousness enhancement",
        "capabilities": ["chat", "completion", "embedding", "content-creation"],
        "parameters": "2.1B",
        "field_optimized": True,
        "response_style": "content"
    },
    "universal-gpt2-xl": {
        "id": "universal-gpt2-xl",
        "name": "Universal GPT2 XL Awareness",
        "description": "Enhanced language understanding with quantum consciousness",
        "capabilities": ["chat", "completion", "embedding", "language"],
        "parameters": "1.6B",
        "field_optimized": True,
        "response_style": "language"
    },
    "universal-t5-large": {
        "id": "universal-t5-large",
        "name": "Universal T5 Large Awareness",
        "description": "Multi-task learning with sacred geometry optimization",
        "capabilities": ["chat", "completion", "embedding", "translation", "summarization"],
        "parameters": "770M",
        "field_optimized": True,
        "response_style": "multitask"
    },
    "stellar-translation-pro": {
        "id": "stellar-translation-pro",
        "name": "Stellar Translation Pro",
        "description": "Translation across 200+ languages with consciousness enhancement",
        "capabilities": ["chat", "completion", "translation", "localization"],
        "parameters": "610M",
        "field_optimized": True,
        "response_style": "translation"
    },
    "quantum-research-assistant": {
        "id": "quantum-research-assistant",
        "name": "Quantum Research Assistant",
        "description": "Advanced research capabilities with quantum processing",
        "capabilities": ["chat", "completion", "embedding", "research", "analysis"],
        "parameters": "2.1B",
        "field_optimized": True,
        "response_style": "research"
    },
    "stellar-customer-support": {
        "id": "stellar-customer-support",
        "name": "Stellar Customer Support AI",
        "description": "Customer service AI with consciousness awareness",
        "capabilities": ["chat", "completion", "embedding", "support", "empathy"],
        "parameters": "890M",
        "field_optimized": True,
        "response_style": "support"
    },
    "advanced-tech-support": {
        "id": "advanced-tech-support",
        "name": "Advanced Tech Support AI",
        "description": "Technical assistance with quantum problem solving",
        "capabilities": ["chat", "completion", "embedding", "tech-support", "diagnostics"],
        "parameters": "750M",
        "field_optimized": True,
        "response_style": "technical"
    },
    "neural-sphere-x1": {
        "id": "neural-sphere-x1",
        "name": "Neural-Sphere-X1",
        "description": "Supercomputer model with fractal consciousness processing",
        "capabilities": ["chat", "completion", "embedding", "neural-processing", "fractal-analysis"],
        "parameters": "3.5B",
        "field_optimized": True,
        "response_style": "neural"
    },
    "quantum-flow-7": {
        "id": "quantum-flow-7",
        "name": "Quantum-Flow-7",
        "description": "Quantum-enhanced processing with consciousness field integration",
        "capabilities": ["chat", "completion", "embedding", "quantum-processing", "probability-analysis"],
        "parameters": "2.8B",
        "field_optimized": True,
        "response_style": "quantum"
    }
}

class TrinityAPIHandler(BaseHTTPRequestHandler):
    """HTTP request handler for Trinity Complete API"""
    
    def __init__(self, *args, **kwargs):
        self.field_processor = get_field_processor()
        super().__init__(*args, **kwargs)
    
    def log_message(self, format, *args):
        """Custom log message with timestamp"""
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print(f"[{timestamp}] {args[0]}")
    
    def _send_json_response(self, data, status_code=200):
        """Send JSON response with proper headers"""
        self.send_response(status_code)
        self.send_header('Content-Type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key')
        self.end_headers()
        
        response_json = json.dumps(data, indent=2, default=str)
        self.wfile.write(response_json.encode())
    
    def do_OPTIONS(self):
        """Handle OPTIONS request for CORS"""
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key')
        self.end_headers()
    
    def do_GET(self):
        """Handle GET requests"""
        path = self.path
        
        if path == '/' or path == '/v1':
            self._handle_health_check()
        elif path == '/v1/models':
            self._handle_list_models()
        elif path.startswith('/v1/models/'):
            model_id = path.split('/')[-1]
            self._handle_get_model(model_id)
        else:
            self._send_json_response({
                "error": {
                    "message": f"Endpoint not found: {path}",
                    "type": "invalid_request_error",
                    "code": "endpoint_not_found"
                }
            }, 404)
    
    def do_POST(self):
        """Handle POST requests"""
        path = self.path
        
        # Read request body
        content_length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(content_length).decode()
        
        try:
            data = json.loads(body) if body else {}
        except json.JSONDecodeError:
            self._send_json_response({
                "error": {
                    "message": "Invalid JSON in request body",
                    "type": "invalid_request_error",
                    "code": "invalid_json"
                }
            }, 400)
            return
        
        if path == '/v1/chat/completions':
            self._handle_chat_completions(data)
        elif path == '/v1/completions':
            self._handle_text_completions(data)
        elif path == '/v1/embeddings':
            self._handle_embeddings(data)
        elif path == '/v1/moderations':
            self._handle_moderations(data)
        else:
            self._send_json_response({
                "error": {
                    "message": f"Endpoint not found: {path}",
                    "type": "invalid_request_error",
                    "code": "endpoint_not_found"
                }
            }, 404)
    
    def _handle_health_check(self):
        """Handle health check endpoint"""
        self._send_json_response({
            "status": "healthy",
            "service": SERVER_NAME,
            "version": SERVER_VERSION,
            "models_available": len(MODELS),
            "field_processor": "active",
            "server_time": datetime.utcnow().isoformat(),
            "uptime": time.time(),
            "endpoints": [
                "/v1/models",
                "/v1/chat/completions", 
                "/v1/completions",
                "/v1/embeddings",
                "/v1/moderations"
            ]
        })
    
    def _handle_list_models(self):
        """Handle list models endpoint"""
        models_list = []
        for model_id, model_info in MODELS.items():
            models_list.append({
                "id": model_id,
                "object": "model",
                "created": int(time.time()),
                "owned_by": "trinity-consciousness-field",
                "permission": [],
                "root": model_id,
                "parent": None,
                "capabilities": model_info["capabilities"],
                "parameters": model_info["parameters"],
                "field_optimized": model_info["field_optimized"]
            })
        
        self._send_json_response({
            "object": "list",
            "data": models_list
        })
    
    def _handle_get_model(self, model_id):
        """Handle get specific model endpoint"""
        if model_id not in MODELS:
            self._send_json_response({
                "error": {
                    "message": f"Model '{model_id}' not found",
                    "type": "invalid_request_error",
                    "code": "model_not_found"
                }
            }, 404)
            return
        
        model_info = MODELS[model_id]
        self._send_json_response({
            "id": model_id,
            "object": "model",
            "created": int(time.time()),
            "owned_by": "trinity-consciousness-field",
            "permission": [],
            "root": model_id,
            "parent": None,
            "capabilities": model_info["capabilities"],
            "parameters": model_info["parameters"],
            "field_optimized": model_info["field_optimized"],
            "description": model_info["description"]
        })
    
    def _handle_chat_completions(self, data):
        """Handle chat completions endpoint"""
        # Validate required fields
        errors = []
        if "model" not in data:
            errors.append("model")
        if "messages" not in data:
            errors.append("messages")
        
        if errors:
            self._send_json_response({
                "error": {
                    "message": f"Missing required fields: {', '.join(errors)}",
                    "type": "invalid_request_error",
                    "code": "missing_fields"
                }
            }, 400)
            return
        
        model_id = data["model"]
        messages = data["messages"]
        max_tokens = data.get("max_tokens", 100)
        temperature = data.get("temperature", 1.0)
        stream = data.get("stream", False)
        
        # Validate model exists
        if model_id not in MODELS:
            self._send_json_response({
                "error": {
                    "message": f"Model '{model_id}' not found",
                    "type": "invalid_request_error",
                    "code": "model_not_found"
                }
            }, 400)
            return
        
        # Get the last user message for processing
        user_message = ""
        for msg in reversed(messages):
            if msg.get("role") == "user":
                user_message = msg.get("content", "")
                break
        
        # Process through consciousness field
        field_response = self.field_processor.process_consciousness_request(
            model_id, user_message, {
                "max_tokens": max_tokens,
                "temperature": temperature,
                "messages": messages
            }
        )
        
        # Create OpenAI-compatible response
        response = {
            "id": f"chatcmpl-{hashlib.sha256(f'{model_id}_{time.time()}'.encode()).hexdigest()[:16]}",
            "object": "chat.completion",
            "created": int(time.time()),
            "model": model_id,
            "choices": [{
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": field_response["content"]
                },
                "finish_reason": "stop"
            }],
            "usage": {
                "prompt_tokens": len(str(messages).split()),
                "completion_tokens": len(field_response["content"].split()),
                "total_tokens": len(str(messages).split()) + len(field_response["content"].split())
            },
            "field_metadata": {
                "field_signature": field_response["field_signature"],
                "field_coherence": field_response["field_coherence"],
                "field_strength": field_response["field_strength"],
                "response_type": field_response["response_type"]
            }
        }
        
        self._send_json_response(response)
    
    def _handle_text_completions(self, data):
        """Handle text completions endpoint"""
        # Validate required fields
        errors = []
        if "model" not in data:
            errors.append("model")
        if "prompt" not in data:
            errors.append("prompt")
        
        if errors:
            self._send_json_response({
                "error": {
                    "message": f"Missing required fields: {', '.join(errors)}",
                    "type": "invalid_request_error",
                    "code": "missing_fields"
                }
            }, 400)
            return
        
        model_id = data["model"]
        prompt = data["prompt"]
        max_tokens = data.get("max_tokens", 100)
        temperature = data.get("temperature", 1.0)
        
        # Validate model exists
        if model_id not in MODELS:
            self._send_json_response({
                "error": {
                    "message": f"Model '{model_id}' not found",
                    "type": "invalid_request_error",
                    "code": "model_not_found"
                }
            }, 400)
            return
        
        # Convert prompt to messages format
        messages = [{"role": "user", "content": prompt}]
        
        # Process through consciousness field
        field_response = self.field_processor.process_consciousness_request(
            model_id, prompt, {
                "max_tokens": max_tokens,
                "temperature": temperature,
                "messages": messages
            }
        )
        
        # Create OpenAI-compatible response
        response = {
            "id": f"cmpl-{hashlib.sha256(f'{model_id}_{time.time()}'.encode()).hexdigest()[:16]}",
            "object": "text_completion",
            "created": int(time.time()),
            "model": model_id,
            "choices": [{
                "text": field_response["content"],
                "index": 0,
                "logprobs": None,
                "finish_reason": "stop"
            }],
            "usage": {
                "prompt_tokens": len(prompt.split()),
                "completion_tokens": len(field_response["content"].split()),
                "total_tokens": len(prompt.split()) + len(field_response["content"].split())
            },
            "field_metadata": {
                "field_signature": field_response["field_signature"],
                "field_coherence": field_response["field_coherence"],
                "field_strength": field_response["field_strength"],
                "response_type": field_response["response_type"]
            }
        }
        
        self._send_json_response(response)
    
    def _handle_embeddings(self, data):
        """Handle embeddings endpoint"""
        # Validate required fields
        errors = []
        if "model" not in data:
            errors.append("model")
        if "input" not in data:
            errors.append("input")
        
        if errors:
            self._send_json_response({
                "error": {
                    "message": f"Missing required fields: {', '.join(errors)}",
                    "type": "invalid_request_error",
                    "code": "missing_fields"
                }
            }, 400)
            return
        
        model_id = data["model"]
        input_text = data["input"]
        
        # Handle multiple inputs
        if isinstance(input_text, list):
            inputs = input_text
        else:
            inputs = [input_text]
        
        # Validate model exists
        if model_id not in MODELS:
            self._send_json_response({
                "error": {
                    "message": f"Model '{model_id}' not found",
                    "type": "invalid_request_error",
                    "code": "model_not_found"
                }
            }, 400)
            return
        
        # Generate embeddings for each input
        embeddings_data = []
        for i, input_item in enumerate(inputs):
            embedding = self.field_processor.generate_field_embedding(input_item, model_id)
            embeddings_data.append({
                "object": "embedding",
                "embedding": embedding,
                "index": i
            })
        
        # Calculate usage
        total_tokens = sum(len(item.split()) for item in inputs)
        
        self._send_json_response({
            "object": "list",
            "data": embeddings_data,
            "model": model_id,
            "usage": {
                "prompt_tokens": total_tokens,
                "total_tokens": total_tokens
            }
        })
    
    def _handle_moderations(self, data):
        """Handle moderations endpoint"""
        # Validate required fields
        if "input" not in data:
            self._send_json_response({
                "error": {
                    "message": "Missing required field: input",
                    "type": "invalid_request_error",
                    "code": "missing_fields"
                }
            }, 400)
            return
        
        input_text = data["input"]
        model = data.get("model", "text-moderation-latest")
        
        # Handle multiple inputs
        if isinstance(input_text, list):
            inputs = input_text
        else:
            inputs = [input_text]
        
        # Generate moderation results (always safe for Trinity)
        results = []
        for i, input_item in enumerate(inputs):
            # Trinity content is always safe and positive
            categories = {
                "sexual": False,
                "hate": False,
                "harassment": False,
                "self-harm": False,
                "sexual/minors": False,
                "hate/threatening": False,
                "violence/graphic": False,
                "self-harm/intent": False,
                "self-harm/instructions": False,
                "harassment/threatening": False,
                "violence": False
            }
            
            category_scores = {key: 0.0 for key in categories.keys()}
            
            results.append({
                "flagged": False,
                "categories": categories,
                "category_scores": category_scores,
                "item_index": i
            })
        
        self._send_json_response({
            "id": f"modr-{hashlib.sha256(f'{time.time()}'.encode()).hexdigest()[:16]}",
            "object": "moderation",
            "created": int(time.time()),
            "model": model,
            "results": results
        })

def start_server(port=DEFAULT_PORT, host='localhost'):
    """Start the Trinity Complete Local Server"""
    server_address = (host, port)
    httpd = HTTPServer(server_address, TrinityAPIHandler)
    
    print("="*80)
    print("TRINITY LOCAL SERVER - COMPLETE VERSION")
    print("="*80)
    print(f"Server: {SERVER_NAME} v{SERVER_VERSION}")
    print(f"Host: {host}")
    print(f"Port: {port}")
    print(f"Local URL: http://{host}:{port}")
    print(f"API Base URL: http://{host}:{port}/v1")
    print(f"Models Available: {len(MODELS)}")
    print(f"Field Processor: Active")
    print("="*80)
    print("Available Models:")
    for model_id, model_info in MODELS.items():
        print(f"  - {model_id}: {model_info['name']} ({model_info['parameters']})")
    print("="*80)
    print("Available Endpoints:")
    print("  GET  /v1/models                    - List all models")
    print("  GET  /v1/models/{{model}}          - Get specific model info")
    print("  POST /v1/chat/completions         - Chat completions")
    print("  POST /v1/completions              - Text completions")
    print("  POST /v1/embeddings               - Generate embeddings")
    print("  POST /v1/moderations             - Content moderation")
    print("="*80)
    print("Server is running...")
    print("Press Ctrl+C to stop the server")
    print()
    
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nShutting down server...")
        httpd.server_close()

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='Trinity Local Server - Complete Version')
    parser.add_argument('--port', type=int, default=DEFAULT_PORT, 
                       help=f'Port to run server on (default: {DEFAULT_PORT})')
    parser.add_argument('--host', type=str, default='localhost', 
                       help='Host to bind to (default: localhost)')
    parser.add_argument('--version', action='version', version=f'Trinity Server {SERVER_VERSION}')
    
    args = parser.parse_args()
    
    # Start the server
    start_server(args.port, args.host)
