// examples/web_server_advanced_router.rs
use gorust::go;
use gorust::runtime;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::time::Duration;

// ============== 路径参数 ==============
#[derive(Clone)]
struct PathParams {
    params: HashMap<String, String>,
}

impl PathParams {
    fn new() -> Self {
        PathParams {
            params: HashMap::new(),
        }
    }

    fn get(&self, key: &str) -> Option<&String> {
        self.params.get(key)
    }

    fn insert(&mut self, key: String, value: String) {
        self.params.insert(key, value);
    }
}

// ============== 响应构建器（修复版） ==============
fn build_response(status: &str, content_type: &str, body: &str) -> Vec<u8> {
    let body_bytes = body.as_bytes();
    let mut response = Vec::with_capacity(512);

    // 直接写入，避免 format! 的临时值问题
    response.extend_from_slice(b"HTTP/1.1 ");
    response.extend_from_slice(status.as_bytes());
    response.extend_from_slice(b"\r\n");

    response.extend_from_slice(b"Content-Type: ");
    response.extend_from_slice(content_type.as_bytes());
    response.extend_from_slice(b"\r\n");

    response.extend_from_slice(b"Content-Length: ");
    response.extend_from_slice(body_bytes.len().to_string().as_bytes());
    response.extend_from_slice(b"\r\n");

    response.extend_from_slice(b"Connection: close\r\n");
    response.extend_from_slice(b"\r\n");
    response.extend_from_slice(body_bytes);

    response
}

fn build_html_response(body: &str) -> Vec<u8> {
    build_response("200 OK", "text/html;charset=utf-8", body)
}

fn build_json_response(body: &str) -> Vec<u8> {
    build_response("200 OK", "application/json", body)
}

// ============== 路由处理器类型 ==============
type HandlerWithParams = fn(PathParams) -> Vec<u8>;

// ============== 高级路由器 ==============
struct AdvancedRouter {
    routes: HashMap<String, HandlerWithParams>,
    dynamic_routes: Vec<(String, HandlerWithParams)>,
}

impl AdvancedRouter {
    fn new() -> Self {
        AdvancedRouter {
            routes: HashMap::new(),
            dynamic_routes: Vec::new(),
        }
    }

    fn add_route(&mut self, path: &str, handler: HandlerWithParams) {
        if path.contains(':') {
            self.dynamic_routes.push((path.to_string(), handler));
        } else {
            self.routes.insert(path.to_string(), handler);
        }
    }

    fn handle(&self, path: &str) -> Vec<u8> {
        // 先查静态路由
        if let Some(handler) = self.routes.get(path) {
            return handler(PathParams::new());
        }

        // 再查动态路由
        for (pattern, handler) in &self.dynamic_routes {
            if let Some(params) = self.match_dynamic_route(pattern, path) {
                return handler(params);
            }
        }

        Self::not_found()
    }

    fn match_dynamic_route(&self, pattern: &str, path: &str) -> Option<PathParams> {
        let pattern_parts: Vec<&str> = pattern.split('/').collect();
        let path_parts: Vec<&str> = path.split('/').collect();

        if pattern_parts.len() != path_parts.len() {
            return None;
        }

        let mut params = PathParams::new();

        for (p_part, path_part) in pattern_parts.iter().zip(path_parts.iter()) {
            if p_part.starts_with(':') {
                let key = p_part[1..].to_string();
                params.insert(key, path_part.to_string());
            } else if p_part != path_part {
                return None;
            }
        }

        Some(params)
    }

    fn not_found() -> Vec<u8> {
        build_response(
            "404 Not Found",
            "text/html",
            "<h1>404 Not Found</h1><p>The requested resource was not found.</p>",
        )
    }

    fn method_not_allowed() -> Vec<u8> {
        build_response(
            "405 Method Not Allowed",
            "text/html",
            "<h1>405 Method Not Allowed</h1><p>Only GET method is supported.</p>",
        )
    }
}

// ============== 静态路由处理器 ==============
fn handle_home(_params: PathParams) -> Vec<u8> {
    let body = r#"<html>
        <head><title>GoRust Web Server</title></head>
        <body>
            <h1>🚀 Welcome to GoRust Web Server</h1>
            <p>High-performance web server powered by GoRust!</p>
            
            <h2>Available Routes:</h2>
            <ul>
                <li><a href="/">/</a> - Home</li>
                <li><a href="/hello">/hello</a> - Hello page</li>
                <li><a href="/json">/json</a> - JSON response</li>
                <li><a href="/about">/about</a> - About page</li>
                <li><a href="/status">/status</a> - Server status</li>
                <li><a href="/user/123">/user/123</a> - Dynamic user (123)</li>
                <li><a href="/user/alice">/user/alice</a> - Dynamic user (alice)</li>
                <li><a href="/post/2024/01/hello-world">/post/2024/01/hello-world</a> - Dynamic post</li>
            </ul>
            
            <h2>Performance:</h2>
            <ul>
                <li>QPS: ~95,000</li>
                <li>Latency: ~0.59ms</li>
                <li>Memory: ~3MB</li>
            </ul>
        </body>
    </html>"#;
    build_html_response(body)
}

fn handle_hello(_params: PathParams) -> Vec<u8> {
    let body = r#"<html>
        <body>
            <h1>👋 Hello from GoRust!</h1>
            <p>Served by goroutine with high performance!</p>
            <p>This request was handled by a lightweight M:N scheduler.</p>
            <p><a href="/">← Back to home</a></p>
        </body>
    </html>"#;
    build_html_response(body)
}

fn handle_json(_params: PathParams) -> Vec<u8> {
    let body = r#"{
        "status": "ok",
        "message": "Hello from GoRust",
        "framework": "rgo",
        "version": "0.2.0",
        "performance": {
            "qps": 95000,
            "latency_ms": 0.59,
            "max_latency_ms": 4.82
        },
        "features": [
            "goroutine",
            "channel",
            "M:N scheduling",
            "work stealing",
            "non-blocking I/O",
            "dynamic routing"
        ]
    }"#;
    build_json_response(body)
}

fn handle_about(_params: PathParams) -> Vec<u8> {
    let body = r#"<html>
        <body>
            <h1>About GoRust</h1>
            <p>GoRust is a lightweight, high-performance runtime for Rust that provides Go-like concurrency.</p>
            
            <h2>Core Features:</h2>
            <ul>
                <li><strong>M:N Goroutine Scheduling</strong> - Efficient user-space threads</li>
                <li><strong>Work Stealing</strong> - Automatic load balancing</li>
                <li><strong>Channel-based Communication</strong> - Safe concurrent message passing</li>
                <li><strong>Non-blocking I/O</strong> - High throughput networking</li>
                <li><strong>Low Memory Footprint</strong> - ~3MB base memory</li>
                <li><strong>High Throughput</strong> - 95,000 req/s</li>
                <li><strong>Low Latency</strong> - ~0.59ms average</li>
            </ul>
            
            <h2>Architecture:</h2>
            <ul>
                <li>G (Goroutine) - User-space task</li>
                <li>P (Processor) - Logical CPU core</li>
                <li>M (Machine) - OS thread</li>
                <li>Scheduler - Work stealing across Ps</li>
            </ul>
            
            <p><a href="/">← Back to home</a></p>
        </body>
    </html>"#;
    build_html_response(body)
}

fn handle_status(_params: PathParams) -> Vec<u8> {
    let mut body = String::new();
    body.push_str(
        r#"<html>
        <head><title>Server Status</title></head>
        <body>
            <h1>📊 Server Status</h1>
            <table border="1" cellpadding="10">
                <tr><th>Metric</th><th>Value</th></tr>
                <tr><td>Framework</td><td>GoRust v0.2.0</td></tr>
                <tr><td>Status</td><td style="color:green">✓ Running</td></tr>
                <tr><td>QPS</td><td>~95,000</td></tr>
                <tr><td>Average Latency</td><td>~0.59ms</td></tr>
                <tr><td>Max Latency</td><td>~4.82ms</td></tr>
                <tr><td>Memory Usage</td><td>~3MB</td></tr>
                <tr><td>Concurrency Model</td><td>M:N Goroutines</td></tr>
                <tr><td>Scheduler</td><td>Work Stealing</td></tr>
            </table>
            <p><a href="/">← Back to home</a></p>
        </body>
    </html>"#,
    );
    build_html_response(&body)
}

// ============== 动态路由处理器 ==============
fn handle_user(params: PathParams) -> Vec<u8> {
    let user_id = params.get("id").map(|s| s.as_str()).unwrap_or("unknown");

    let mut body = String::new();
    body.push_str(
        r#"<html>
        <body>
            <h1>👤 User Profile</h1>
            <p><strong>User ID:</strong> "#,
    );
    body.push_str(user_id);
    body.push_str(
        r#"</p>
            <p><strong>Page:</strong> Dynamic route handling</p>
            <p>This page demonstrates dynamic routing with path parameters.</p>
            <p><a href="/">← Back to home</a></p>
        </body>
    </html>"#,
    );

    build_html_response(&body)
}

fn handle_post(params: PathParams) -> Vec<u8> {
    let year = params.get("year").map(|s| s.as_str()).unwrap_or("unknown");
    let month = params.get("month").map(|s| s.as_str()).unwrap_or("unknown");
    let slug = params.get("slug").map(|s| s.as_str()).unwrap_or("unknown");

    let mut body = String::new();
    body.push_str(
        r#"<html>
        <body>
            <h1>📝 Blog Post</h1>
            <p><strong>Date:</strong> "#,
    );
    body.push_str(year);
    body.push_str("-");
    body.push_str(month);
    body.push_str(
        r#"</p>
            <p><strong>Slug:</strong> "#,
    );
    body.push_str(slug);
    body.push_str(
        r#"</p>
            <p>This is a dynamically routed blog post page.</p>
            <p>The routing pattern <code>/post/:year/:month/:slug</code> matches this URL.</p>
            <p><a href="/">← Back to home</a></p>
        </body>
    </html>"#,
    );

    build_html_response(&body)
}

// ============== HTTP 请求解析 ==============
fn parse_request(buffer: &[u8]) -> Option<(String, String)> {
    let request_str = String::from_utf8_lossy(buffer);
    let first_line = request_str.lines().next()?;
    let parts: Vec<&str> = first_line.split_whitespace().collect();

    if parts.len() >= 2 {
        let method = parts[0].to_string();
        let path = parts[1].to_string();
        Some((method, path))
    } else {
        None
    }
}

// ============== 全局路由器 ==============
lazy_static! {
    static ref ROUTER: AdvancedRouter = {
        let mut router = AdvancedRouter::new();

        // 静态路由
        router.add_route("/", handle_home);
        router.add_route("/hello", handle_hello);
        router.add_route("/json", handle_json);
        router.add_route("/about", handle_about);
        router.add_route("/status", handle_status);

        // 动态路由
        router.add_route("/user/:id", handle_user);
        router.add_route("/post/:year/:month/:slug", handle_post);

        router
    };
}

// ============== 连接处理 ==============
fn handle_connection(mut stream: TcpStream) {
    let _ = stream.set_nonblocking(true);

    let mut buffer = [0; 4096];
    let mut wait_us = 10;

    loop {
        match stream.read(&mut buffer) {
            Ok(0) => return,
            Ok(n) => {
                if let Some((method, path)) = parse_request(&buffer[..n]) {
                    let response = if method != "GET" {
                        AdvancedRouter::method_not_allowed()
                    } else {
                        ROUTER.handle(&path)
                    };
                    let _ = stream.write_all(&response);
                } else {
                    let response = build_html_response("<h1>400 Bad Request</h1>");
                    let _ = stream.write_all(&response);
                }
                let _ = stream.flush();
                return;
            }
            Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {
                std::thread::sleep(std::time::Duration::from_micros(wait_us));
                wait_us = (wait_us * 2).min(500);
                gorust::yield_now();
            }
            Err(_) => return,
        }
    }
}

// ============== 主函数 ==============
#[runtime]
fn main() -> std::io::Result<()> {
        // 初始化日志
    // let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warning"))
    //     .is_test(true)
    //     .try_init();

    println!("╔════════════════════════════════════════════════════════════╗");
    println!("║         GoRust Advanced Router Web Server                 ║");
    println!("║                  High-performance HTTP Server              ║");
    println!("╚════════════════════════════════════════════════════════════╝");
    println!();
    println!("📍 Server running at: http://127.0.0.1:8080");
    println!();
    println!("📋 Available Routes:");
    println!("   ┌─────────────────────────────────────────────────────────┐");
    println!("   │ Static Routes:                                          │");
    println!("   │   GET  /              - Home page                       │");
    println!("   │   GET  /hello         - Hello page                      │");
    println!("   │   GET  /json          - JSON response                   │");
    println!("   │   GET  /about         - About page                      │");
    println!("   │   GET  /status        - Server status                   │");
    println!("   │                                                        │");
    println!("   │ Dynamic Routes:                                         │");
    println!("   │   GET  /user/:id      - User profile (dynamic ID)       │");
    println!("   │   GET  /post/:year/:month/:slug - Blog post            │");
    println!("   └─────────────────────────────────────────────────────────┘");
    println!();
    println!("💡 Examples:");
    println!("   curl http://127.0.0.1:8080/user/123");
    println!("   curl http://127.0.0.1:8080/post/2024/01/hello-world");
    println!();
    println!("⚡ Performance: ~95,000 req/s | Latency: ~0.59ms");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!();

    let listener = TcpListener::bind("127.0.0.1:8080")?;
    listener.set_nonblocking(true)?;

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                go(move || {
                    handle_connection(stream);
                });
            }
            Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {
                std::thread::sleep(Duration::from_micros(100));
            }
            Err(e) => {
                eprintln!("Connection failed: {}", e);
            }
        }
    }

    Ok(())
}
