use clap::Parser;
use std::path::PathBuf;
use axum::{Extension, Router, extract::Request, response::IntoResponse, routing::any};
use tokio::net::TcpListener;
use dav_server::DavHandler;
use markbase::webdav::MarkBaseWebDAV;
use markbase::filetree::FileTree;

#[derive(Parser)]
struct Args {
    #[arg(short, long, default_value = "8080")]
    port: u16,
    
    #[arg(short, long)]
    user: String,
}

fn main() {
    std::env::set_var("RUST_LOG", "info");
    
    tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(async_main());
}

async fn async_main() {
    let args = Args::parse();
    
    let db_path = PathBuf::from(FileTree::user_db_path(&args.user));
    
    if !db_path.exists() {
        eprintln!("User database not found: {}", db_path.display());
        return;
    }
    
    println!("=== MarkBase WebDAV Server ===");
    println!("User: {}", args.user);
    println!("Port: {}", args.port);
    println!("Database: {}", db_path.display());
    println!("");
    
    let webdav = MarkBaseWebDAV::new(args.user.clone(), db_path);
    let dav_handler = webdav.create_handler();
    
    let addr = format!("127.0.0.1:{}", args.port);
    let listener = TcpListener::bind(&addr).await.expect("Failed to bind port");
    
    let router = Router::new()
        .route("/webdav", any(handle_dav))
        .route("/webdav/", any(handle_dav))
        .route("/webdav/{*path}", any(handle_dav))
        .layer(Extension(dav_handler));
    
    println!("Listening on: http://{}", addr);
    println!("Mount with Finder:");
    println!("  Connect to Server → http://localhost:{}/webdav", args.port);
    println!("");
    println!("Press Ctrl+C to stop...");
    
    if let Err(e) = axum::serve(listener, router).await {
        eprintln!("Server error: {}", e);
    }
}

async fn handle_dav(Extension(dav): Extension<DavHandler>, req: Request) -> impl IntoResponse {
    println!("{} {}", req.method(), req.uri().path());
    dav.handle(req).await
}