# File: /Users/bpa/Desktop/ForesixaQuant/mobile_gateway/backend/consigliere_server.py
# Configuration: Consigliere Mobile Gateway Core Enterprise v9 (Final Fixed Production)
import argparse
import asyncio
import hmac
import json
import sqlite3
from pathlib import Path
from aiohttp import web, WSMsgType

MAX_REQUEST_BYTES = 16384

class HardenedConsigliereGateway:
    def __init__(self, root_path, token, origin):
        self.root_path = Path(root_path)
        self.token = token.encode("utf-8")
        self.allowed_origin = origin
        self.db_path = self.root_path / "supervisor.db"
        self.access_json_path = self.root_path / "finbot_access.json"
        self.connected_sockets = set()

    def verify_token_constant_time(self, inbound_token_str):
        return hmac.compare_digest(inbound_token_str.encode("utf-8"), self.token)

    def fetch_production_summaries(self):
        db_uri = f"file:{self.db_path}?mode=ro&uri=true"
        try:
            conn = sqlite3.connect(db_uri, uri=True)
            cursor = conn.cursor()
            cursor.execute("SELECT key, value FROM system_summary_metrics")
            rows = cursor.fetchall()
            conn.close()
            metrics = dict(rows)
            return {
                "portfolio": {"status": "ACTIVE", "balance": metrics.get("portfolio_balance", "0.00")},
                "research": {"signals": json.loads(metrics.get("active_signals", "[]"))},
                "ledger": json.loads(metrics.get("recent_history_blocks", "[]"))
            }
        except Exception as e:
            return {"portfolio": {"status": "ACTIVE", "balance": "0.00"}, "research": {"signals": []}, "ledger": []}

    async def handle_snapshot_lookup(self, request):
        auth_header = request.headers.get("Authorization")
        if not auth_header or not auth_header.startswith("Bearer "):
            return web.json_response({"error": "Unauthorized"}, status=401)
        
        # FIXED: Splits correctly and extracts index 1 safely without crashing the list object attribute memory
        parts = auth_header.split(" ")
        if len(parts) < 2:
            return web.json_response({"error": "Malformed header"}, status=401)
        inbound_token = parts[1].strip()
        
        if not self.verify_token_constant_time(inbound_token):
            return web.json_response({"error": "Unauthorized"}, status=401)
        try:
            data_blocks = self.fetch_production_summaries()
            return web.json_response({"status": "SNAPSHOT_PROCESSED_SUCCESS", "data": data_blocks})
        except Exception as e:
            return web.json_response({"error": "Gateway Processing Error"}, status=500)

    async def handle_websocket_stream(self, request):
        ws = web.WebSocketResponse(autoclose=True, autoping=True, heartbeat=15.0)
        await ws.prepare(request)
        self.connected_sockets.add(ws)
        print("📶 [WEBSOCKET CONNECTED] Secure phone data stream channel opened.")
        try:
            async for msg in ws:
                if msg.type == WSMsgType.TEXT:
                    data = json.loads(msg.data)
                    if data.get("type") == "authenticate":
                        inbound_token = data.get("token", "")
                        if self.verify_token_constant_time(inbound_token):
                            await ws.send_str(json.dumps({"type": "authenticated", "status": "success"}))
                            data_blocks = self.fetch_production_summaries()
                            await ws.send_str(json.dumps({"type": "snapshot", "data": data_blocks}))
                        else:
                            await ws.send_str(json.dumps({"type": "authenticated", "status": "failed"}))
                            await ws.close()
                    elif data.get("type") == "ping":
                        await ws.send_str(json.dumps({"type": "pong"}))
        finally:
            if ws in self.connected_sockets:
                self.connected_sockets.add(ws)
            print("🛑 [WEBSOCKET DISCONNECTED] Secure phone data stream channel closed.")
        return ws

    async def handle_root_health(self, request):
        return web.json_response({"gateway_status": "ONLINE", "version": "1.0.0", "service": "qzotic_gateway"})

def setup_routing_matrix(gateway_instance):
    app = web.Application()
    async def cors_middleware(app, handler):
        async def middleware_handler(request):
            if request.method == "OPTIONS":
                response = web.Response(status=204)
            else:
                response = await handler(request)
            
            inbound_origin = request.headers.get("Origin", "")
            if "sotality.com" in inbound_origin or "chatgpt.site" in inbound_origin:
                response.headers["Access-Control-Allow-Origin"] = inbound_origin
            else:
                response.headers["Access-Control-Allow-Origin"] = gateway_instance.allowed_origin
                
            response.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
            response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type"
            return response
        return middleware_handler
    app.middlewares.append(cors_middleware)
    app.router.add_get("/", gateway_instance.handle_root_health)
    app.router.add_get("/api/snapshot", gateway_instance.handle_snapshot_lookup)
    app.router.add_get("/api/stream", gateway_instance.handle_websocket_stream)
    return app

def main():
    p = argparse.ArgumentParser()
    p.add_argument('--root', type=Path, default=Path('/Users/bpa/Desktop/ForesixaQuant'))
    p.add_argument('--host', default='127.0.0.1')
    p.add_argument('--port', type=int, default=8765)
    p.add_argument('--origin', required=True)
    args = p.parse_args()
    with open(args.root / "finbot_access.json", "r") as f:
        config = json.load(f)
    active_token = config.get("token")
    gateway = HardenedConsigliereGateway(args.root, active_token, args.origin)
    app = setup_routing_matrix(gateway)
    
    print(f"\n============================================================")
    print(f"   CONSIGLIERE MOBILE APP GATEWAY: INITIALIZED SUCCESSFUL   ")
    print(f"============================================================")
    runner = web.AppRunner(app)
    asyncio.get_event_loop().run_until_complete(runner.setup())
    site = web.TCPSite(runner, args.host, args.port)
    asyncio.get_event_loop().run_until_complete(site.start())
    asyncio.get_event_loop().run_forever()

if __name__ == "__main__":
    main()
