#!/usr/bin/env python3
"""
ASPEKT Unified Dashboard Server
Serves: main dashboard, client dashboard, themed gateway proxy
Port: 8899 (exposed via Tailscale funnel)
"""

import http.server
import socketserver
import urllib.request
import os
import json
import signal
import sys

WORKSPACE = '/Users/neoclaw/.openclaw/workspace'
GATEWAY_PORT = 18789
LISTEN_PORT = 8899

class ASPEKTHandler(http.server.BaseHTTPRequestHandler):
    def log_message(self, format, *args):
        pass  # Suppress access logs

    def do_GET(self):
        path = self.path.split('?')[0]  # Strip query params

        # Route: Main Dashboard
        if path == '/' or path == '/dashboard.html':
            self._serve_file(os.path.join(WORKSPACE, 'dashboard.html'), 'text/html')

        # Route: Client Dashboard
        elif path == '/clients' or path == '/client-dashboard.html':
            self._serve_file(os.path.join(WORKSPACE, 'client-dashboard.html'), 'text/html')

        # Route: Themed Gateway
        elif path == '/gateway' or path == '/gateway/':
            self._serve_file(os.path.join(WORKSPACE, 'gateway-index.html'), 'text/html')

        # Route: ASPEKT Theme CSS
        elif path == '/aspekt-gateway-theme.css':
            self._serve_file(os.path.join(WORKSPACE, 'aspekt-gateway-theme.css'), 'text/css')

        # Route: Dashboard state JSON (live data)
        elif path == '/dashboard-state.json':
            self._serve_file(os.path.join(WORKSPACE, 'live-dashboard-state.json'), 'application/json')

        # Route: Client health check config (for client dashboard)
        elif path == '/tools/client-health-check/config.json':
            self._serve_file(os.path.join(WORKSPACE, 'tools/client-health-check/config.json'), 'application/json')

        # Route: Workspace assets first (avatars, images, etc.)
        elif path.startswith('/assets/'):
            filepath = os.path.join(WORKSPACE, path[1:])
            if os.path.isfile(filepath):
                content_type = self._guess_type(filepath)
                self._serve_file(filepath, content_type)
            else:
                # Fall back to gateway proxy for unknown assets
                self._proxy_gateway(path)

        # Route: Gateway assets (proxy to real gateway)
        elif path.startswith('/gateway/assets/'):
            asset_path = path.replace('/gateway/', '/')
            self._proxy_gateway(asset_path)

        # Route: Gateway favicon files
        elif path.startswith('/gateway/favicon') or path.startswith('/gateway/apple-touch'):
            asset_path = path.replace('/gateway/', '/')
            self._proxy_gateway(asset_path)

        # Route: Gateway API (proxy)
        elif path.startswith('/api/') or path.startswith('/ws'):
            self._proxy_gateway(self.path)

        # Route: Workspace static files (images, etc.)
        elif path.startswith('/static/'):
            filepath = os.path.join(WORKSPACE, path[8:])  # Strip /static/
            if os.path.isfile(filepath):
                content_type = self._guess_type(filepath)
                self._serve_file(filepath, content_type)
            else:
                self.send_error(404)

        # Route: Workspace markdown docs (live)
        elif path.endswith('.md'):
            # Serve markdown files from workspace root
            filename = path[1:] if path.startswith('/') else path
            filepath = os.path.join(WORKSPACE, filename)
            if os.path.isfile(filepath):
                self._serve_file(filepath, 'text/markdown; charset=utf-8')
            else:
                self.send_error(404, f'Document not found: {filename}')

        else:
            self.send_error(404, f'Not Found: {path}')

    def _serve_file(self, filepath, content_type):
        try:
            with open(filepath, 'rb') as f:
                data = f.read()
            self.send_response(200)
            self.send_header('Content-Type', content_type)
            self.send_header('Content-Length', str(len(data)))
            self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(data)
        except FileNotFoundError:
            self.send_error(404, f'File not found')
        except Exception as e:
            self.send_error(500, str(e))

    def _proxy_gateway(self, path):
        try:
            url = f'http://localhost:{GATEWAY_PORT}{path}'
            req = urllib.request.Request(url)
            with urllib.request.urlopen(req, timeout=10) as response:
                data = response.read()
                self.send_response(response.status)
                for header, value in response.headers.items():
                    if header.lower() not in ('connection', 'transfer-encoding', 'content-encoding'):
                        self.send_header(header, value)
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(data)
        except Exception as e:
            self.send_error(502, f'Gateway proxy error: {e}')



    def _guess_type(self, filepath):
        ext = os.path.splitext(filepath)[1].lower()
        types = {
            '.html': 'text/html',
            '.css': 'text/css',
            '.js': 'application/javascript',
            '.json': 'application/json',
            '.png': 'image/png',
            '.jpg': 'image/jpeg',
            '.jpeg': 'image/jpeg',
            '.gif': 'image/gif',
            '.svg': 'image/svg+xml',
            '.ico': 'image/x-icon',
            '.webp': 'image/webp',
            '.woff2': 'font/woff2',
        }
        return types.get(ext, 'application/octet-stream')


class ReusableTCPServer(socketserver.TCPServer):
    allow_reuse_address = True


def main():
    server = ReusableTCPServer(('0.0.0.0', LISTEN_PORT), ASPEKTHandler)

    def shutdown(signum, frame):
        server.shutdown()
        sys.exit(0)

    signal.signal(signal.SIGTERM, shutdown)
    signal.signal(signal.SIGINT, shutdown)

    print(f'ASPEKT Server running on port {LISTEN_PORT}')
    print(f'  Dashboard:  http://localhost:{LISTEN_PORT}/')
    print(f'  Clients:    http://localhost:{LISTEN_PORT}/clients')
    print(f'  Gateway:    http://localhost:{LISTEN_PORT}/gateway')
    server.serve_forever()


if __name__ == '__main__':
    main()
