(** Smoke test: parse SX, render to node tree, measure, layout, paint to PNG. *)

open Sx_native.Sx_native_types

let demo_sx = {|
(div :class "flex flex-col items-center gap-6 p-8 bg-stone-50"
  (h1 :class "text-3xl font-bold text-stone-800" "SX Native Browser")
  (p :class "text-stone-500" "Rendering s-expressions directly to pixels")
  (div :class "flex gap-4 items-center"
    (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow"
      (h3 :class "font-bold text-stone-700" "No HTML")
      (p :class "text-sm text-stone-500" "This is not a web page"))
    (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow"
      (h3 :class "font-bold text-stone-700" "No CSS")
      (p :class "text-sm text-stone-500" "Tailwind classes parsed to native styles"))
    (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow"
      (h3 :class "font-bold text-stone-700" "No JavaScript")
      (p :class "text-sm text-stone-500" "The SX evaluator does everything")))
  (div :class "p-6 rounded-lg bg-violet-600"
    (p :class "text-white text-lg font-bold" "5000 lines of OCaml instead of 35 million lines of browser engine")))
|}

let rec count_nodes (node : node) : int =
  1 + List.fold_left (fun acc c -> acc + count_nodes c) 0 node.children

let rec print_tree indent (node : node) =
  let prefix = String.make (indent * 2) ' ' in
  let text_info = match node.text with
    | Some t -> Printf.sprintf " \"%s\"" (if String.length t > 30 then String.sub t 0 30 ^ "..." else t)
    | None -> ""
  in
  let size_info = Printf.sprintf " [%.0fx%.0f @ (%.0f,%.0f)]" node.box.w node.box.h node.box.x node.box.y in
  Printf.printf "%s<%s>%s%s\n" prefix node.tag text_info size_info;
  List.iter (print_tree (indent + 1)) node.children

let () =
  Printf.printf "=== SX Native Browser Smoke Test ===\n\n";

  (* 1. Parse *)
  let values = Sx_parser.parse_all demo_sx in
  Printf.printf "1. Parsed %d top-level form(s)\n" (List.length values);

  (* 2. Render to node tree *)
  let root = Sx_native.Sx_native_render.render_page values in
  let n = count_nodes root in
  Printf.printf "2. Render tree: %d nodes, root tag=%s\n" n root.tag;

  (* 3. Create Cairo surface for measurement *)
  let surface = Cairo.Image.create Cairo.Image.ARGB32 ~w:1024 ~h:768 in
  let cr = Cairo.create surface in

  (* 4. Measure *)
  Sx_native.Sx_native_layout.measure cr root;
  Printf.printf "3. Measured intrinsic size: %.0f x %.0f\n" root.box.w root.box.h;

  (* 5. Layout *)
  Sx_native.Sx_native_layout.layout root 0. 0. 1024. 732.;
  Printf.printf "4. Layout complete, root positioned at (%.0f, %.0f) size %.0f x %.0f\n"
    root.box.x root.box.y root.box.w root.box.h;

  (* 6. Paint *)
  Sx_native.Sx_native_paint.paint_scene cr root "sx://demo" 1024. 768.;
  Cairo.Surface.flush surface;

  (* 7. Write PNG *)
  let png_path = "/tmp/sx_browser_test.png" in
  Cairo.PNG.write surface png_path;
  Printf.printf "5. Rendered to %s\n\n" png_path;

  (* Print tree *)
  Printf.printf "=== Render Tree ===\n";
  print_tree 0 root;

  Cairo.Surface.finish surface;
  Printf.printf "\n=== All OK! ===\n"
