///|
/// WebDriver request routing
/// Parses HTTP method + path into WebDriverCommand

///|
/// Parse HTTP request into WebDriverRequest
pub fn parse_request(
  method_str : String,
  path : String,
  body : String,
) -> WebDriverRequest {
  let http_method = match method_str.to_upper() {
    "GET" => HttpMethod::Get
    "POST" => HttpMethod::Post
    "DELETE" => HttpMethod::Delete
    _ => HttpMethod::Get // Default to GET for unknown methods
  }
  let command = parse_command(http_method, path)
  { http_method, command, body }
}

///|
/// Parse path into WebDriverCommand
fn parse_command(http_method : HttpMethod, path : String) -> WebDriverCommand {
  // Remove leading slash and split by '/'
  let path : String = if path.has_prefix("/") && path.length() > 1 {
    let buf = StringBuilder::new()
    let mut skip_first = true
    for c in path.iter() {
      if skip_first {
        skip_first = false
        continue
      }
      buf.write_char(c)
    }
    buf.to_string()
  } else if path == "/" {
    ""
  } else {
    path
  }
  let parts = split_path(path)
  match (http_method, parts) {
    // Status
    (HttpMethod::Get, ["status"]) => Status

    // Session management
    (HttpMethod::Post, ["session"]) => NewSession
    (HttpMethod::Get, ["session", session_id]) => GetSession(session_id~)
    (HttpMethod::Delete, ["session", session_id]) => DeleteSession(session_id~)

    // Timeouts
    (HttpMethod::Get, ["session", session_id, "timeouts"]) =>
      GetTimeouts(session_id~)
    (HttpMethod::Post, ["session", session_id, "timeouts"]) =>
      SetTimeouts(session_id~)

    // Navigation
    (HttpMethod::Post, ["session", session_id, "url"]) =>
      NavigateTo(session_id~)
    (HttpMethod::Get, ["session", session_id, "url"]) =>
      GetCurrentUrl(session_id~)
    (HttpMethod::Post, ["session", session_id, "back"]) => Back(session_id~)
    (HttpMethod::Post, ["session", session_id, "forward"]) =>
      Forward(session_id~)
    (HttpMethod::Post, ["session", session_id, "refresh"]) =>
      Refresh(session_id~)
    (HttpMethod::Get, ["session", session_id, "title"]) => GetTitle(session_id~)

    // Window
    (HttpMethod::Get, ["session", session_id, "window"]) =>
      GetWindowHandle(session_id~)
    (HttpMethod::Delete, ["session", session_id, "window"]) =>
      CloseWindow(session_id~)
    (HttpMethod::Post, ["session", session_id, "window"]) =>
      SwitchToWindow(session_id~)
    (HttpMethod::Get, ["session", session_id, "window", "handles"]) =>
      GetWindowHandles(session_id~)
    (HttpMethod::Post, ["session", session_id, "window", "new"]) =>
      NewWindow(session_id~)
    (HttpMethod::Post, ["session", session_id, "frame"]) =>
      SwitchToFrame(session_id~)
    (HttpMethod::Post, ["session", session_id, "frame", "parent"]) =>
      SwitchToParentFrame(session_id~)
    (HttpMethod::Get, ["session", session_id, "window", "rect"]) =>
      GetWindowRect(session_id~)
    (HttpMethod::Post, ["session", session_id, "window", "rect"]) =>
      SetWindowRect(session_id~)
    (HttpMethod::Post, ["session", session_id, "window", "maximize"]) =>
      MaximizeWindow(session_id~)
    (HttpMethod::Post, ["session", session_id, "window", "minimize"]) =>
      MinimizeWindow(session_id~)
    (HttpMethod::Post, ["session", session_id, "window", "fullscreen"]) =>
      FullscreenWindow(session_id~)

    // Element finding
    (HttpMethod::Post, ["session", session_id, "element"]) =>
      FindElement(session_id~)
    (HttpMethod::Post, ["session", session_id, "elements"]) =>
      FindElements(session_id~)
    (HttpMethod::Post, ["session", session_id, "element", element_id, "element"]
    ) => FindElementFromElement(session_id~, element_id~)
    (
      HttpMethod::Post,
      ["session", session_id, "element", element_id, "elements"],
    ) => FindElementsFromElement(session_id~, element_id~)
    (HttpMethod::Get, ["session", session_id, "element", "active"]) =>
      GetActiveElement(session_id~)

    // Element properties
    (HttpMethod::Get, ["session", session_id, "element", element_id, "selected"]
    ) => IsElementSelected(session_id~, element_id~)
    (
      HttpMethod::Get,
      ["session", session_id, "element", element_id, "attribute", name],
    ) => GetElementAttribute(session_id~, element_id~, name~)
    (
      HttpMethod::Get,
      ["session", session_id, "element", element_id, "property", name],
    ) => GetElementProperty(session_id~, element_id~, name~)
    (
      HttpMethod::Get,
      ["session", session_id, "element", element_id, "css", name],
    ) => GetElementCssValue(session_id~, element_id~, name~)
    (HttpMethod::Get, ["session", session_id, "element", element_id, "text"]) =>
      GetElementText(session_id~, element_id~)
    (HttpMethod::Get, ["session", session_id, "element", element_id, "name"]) =>
      GetElementTagName(session_id~, element_id~)
    (HttpMethod::Get, ["session", session_id, "element", element_id, "rect"]) =>
      GetElementRect(session_id~, element_id~)
    (HttpMethod::Get, ["session", session_id, "element", element_id, "enabled"]) =>
      IsElementEnabled(session_id~, element_id~)

    // Element interaction
    (HttpMethod::Post, ["session", session_id, "element", element_id, "click"]) =>
      ElementClick(session_id~, element_id~)
    (HttpMethod::Post, ["session", session_id, "element", element_id, "clear"]) =>
      ElementClear(session_id~, element_id~)
    (HttpMethod::Post, ["session", session_id, "element", element_id, "value"]) =>
      ElementSendKeys(session_id~, element_id~)

    // Document
    (HttpMethod::Get, ["session", session_id, "source"]) =>
      GetPageSource(session_id~)
    (HttpMethod::Post, ["session", session_id, "execute", "sync"]) =>
      ExecuteScript(session_id~)
    (HttpMethod::Post, ["session", session_id, "execute", "async"]) =>
      ExecuteAsyncScript(session_id~)

    // Cookies
    (HttpMethod::Get, ["session", session_id, "cookie"]) =>
      GetAllCookies(session_id~)
    (HttpMethod::Get, ["session", session_id, "cookie", name]) =>
      GetNamedCookie(session_id~, name~)
    (HttpMethod::Post, ["session", session_id, "cookie"]) =>
      AddCookie(session_id~)
    (HttpMethod::Delete, ["session", session_id, "cookie", name]) =>
      DeleteCookie(session_id~, name~)
    (HttpMethod::Delete, ["session", session_id, "cookie"]) =>
      DeleteAllCookies(session_id~)

    // Actions
    (HttpMethod::Post, ["session", session_id, "actions"]) =>
      PerformActions(session_id~)
    (HttpMethod::Delete, ["session", session_id, "actions"]) =>
      ReleaseActions(session_id~)

    // Alerts
    (HttpMethod::Post, ["session", session_id, "alert", "dismiss"]) =>
      DismissAlert(session_id~)
    (HttpMethod::Post, ["session", session_id, "alert", "accept"]) =>
      AcceptAlert(session_id~)
    (HttpMethod::Get, ["session", session_id, "alert", "text"]) =>
      GetAlertText(session_id~)
    (HttpMethod::Post, ["session", session_id, "alert", "text"]) =>
      SendAlertText(session_id~)

    // Screenshot
    (HttpMethod::Get, ["session", session_id, "screenshot"]) =>
      TakeScreenshot(session_id~)
    (
      HttpMethod::Get,
      ["session", session_id, "element", element_id, "screenshot"],
    ) => TakeElementScreenshot(session_id~, element_id~)

    // Print
    (HttpMethod::Post, ["session", session_id, "print"]) =>
      PrintPage(session_id~)

    // Unknown
    _ => Unknown(path~)
  }
}

///|
/// Split path by '/'
fn split_path(path : String) -> Array[String] {
  let parts : Array[String] = []
  let current = StringBuilder::new()
  for c in path {
    if c == '/' {
      let s = current.to_string()
      if !s.is_empty() {
        parts.push(s)
      }
      current.reset()
    } else {
      current.write_char(c)
    }
  }
  let s = current.to_string()
  if !s.is_empty() {
    parts.push(s)
  }
  parts
}