#!/usr/bin/env python3
"""
Simple public proxy to expose Next.js server
"""

import http.server
import socketserver
import urllib.request
import urllib.error
import threading
import time
import sys

class ProxyHandler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        self.proxy_request('GET')

    def do_POST(self):
        self.proxy_request('POST')

    def do_PUT(self):
        self.proxy_request('PUT')

    def do_DELETE(self):
        self.proxy_request('DELETE')

    def do_HEAD(self):
        self.proxy_request('HEAD')

    def do_OPTIONS(self):
        self.proxy_request('OPTIONS')

    def proxy_request(self, method):
        try:
            # Target Next.js server
            target_url = f"http://localhost:3005{self.path}"

            # Create request
            req = urllib.request.Request(target_url, method=method)

            # Copy headers (except host)
            for header, value in self.headers.items():
                if header.lower() not in ['host', 'connection']:
                    req.add_header(header, value)

            # Handle request body for POST/PUT
            if method in ['POST', 'PUT']:
                content_length = int(self.headers.get('Content-Length', 0))
                if content_length > 0:
                    body = self.rfile.read(content_length)
                    req.data = body

            # Make request to Next.js server
            with urllib.request.urlopen(req) as response:
                # Send response back to client
                self.send_response(response.status)

                # Copy response headers
                for header, value in response.headers.items():
                    if header.lower() not in ['transfer-encoding', 'connection']:
                        self.send_header(header, value)
                self.end_headers()

                # Send response body
                self.wfile.write(response.read())

        except urllib.error.HTTPError as e:
            self.send_error(e.code, str(e.reason))
        except Exception as e:
            self.send_error(500, f"Proxy error: {str(e)}")

    def log_message(self, format, *args):
        # Custom logging to show public access
        if self.address_string() != '127.0.0.1':
            print(f"🌐 PUBLIC ACCESS from {self.address_string()}: {format % args}")
        else:
            print(f"🏠 LOCAL ACCESS: {format % args}")

def run_proxy(port=8080):
    """Run the public proxy server"""

    print("🚀 Starting Public Proxy Server")
    print("=" * 50)
    print(f"📡 Proxying localhost:3005 → 0.0.0.0:{port}")
    print(f"🌐 Public URL: http://YOUR_SERVER_IP:{port}")
    print(f"🏠 Local URL: http://localhost:{port}")
    print()
    print("🔒 Security Notes:")
    print("• Only exposing the homepage (GET requests)")
    print("• No sensitive data or admin access")
    print("• Rate limiting not implemented")
    print("• Use for demo purposes only!")
    print()
    print("Press Ctrl+C to stop...")
    print()

    # Get server IP
    import socket
    hostname = socket.gethostname()
    try:
        server_ip = socket.gethostbyname(hostname)
        print(f"💻 Server IP: {server_ip}")
        print(f"🌐 Access URL: http://{server_ip}:{port}")
    except:
        print("💻 Could not determine server IP")
    print()

    with socketserver.TCPServer(("", port), ProxyHandler) as httpd:
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\n🛑 Shutting down proxy server...")
            httpd.shutdown()

if __name__ == "__main__":
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
    run_proxy(port)
