// Example: Building and navigating a CST for S-expressions
// Input: (let x (+ 1 2))

// Define syntax kinds for S-expressions

///|
fn root_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(10)
}

///|
fn list_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(11)
}

///|
fn atom_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(12)
}

///|
fn lparen_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(13)
}

///|
fn rparen_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(14)
}

///|
fn whitespace_kind() -> @cst.SyntaxKind {
  @cst.SyntaxKind::new(15)
}

///|
fn main {
  // Build CST for: (let x (+ 1 2))
  let builder = @cst.GreenNodeBuilder::new()

  builder.start_node(root_kind())
  builder.start_node(list_kind()) // (let x (+ 1 2))
  builder.token(lparen_kind(), "(")
  builder.token(atom_kind(), "let")
  builder.token(whitespace_kind(), " ")
  builder.token(atom_kind(), "x")
  builder.token(whitespace_kind(), " ")

  // Nested list: (+ 1 2)
  builder.start_node(list_kind())
  builder.token(lparen_kind(), "(")
  builder.token(atom_kind(), "+")
  builder.token(whitespace_kind(), " ")
  builder.token(atom_kind(), "1")
  builder.token(whitespace_kind(), " ")
  builder.token(atom_kind(), "2")
  builder.token(rparen_kind(), ")")
  builder.finish_node()

  builder.token(rparen_kind(), ")")
  builder.finish_node()
  builder.finish_node()

  let green = builder.finish()

  // Navigate with red tree
  let root = @cst.SyntaxNode::new_root(green)

  println("CST Structure:")
  println("==============")
  print_tree(root, 0)

  println("")
  println("Text ranges:")
  println("============")
  print_ranges(root, 0)
}

///|
fn print_tree(node : @cst.SyntaxNode, depth : Int) -> Unit {
  let indent = String::make(depth * 2, ' ')
  println("\{indent}Node(kind=\{node.kind().raw()})")

  for child in node.children() {
    match child {
      @cst.SyntaxElement::Node(n) => print_tree(n, depth + 1)
      @cst.SyntaxElement::Token(t) => {
        let token_indent = String::make((depth + 1) * 2, ' ')
        println(
          "\{token_indent}Token(kind=\{t.kind().raw()}, text=\"\{t.text()}\")",
        )
      }
    }
  }
}

///|
fn print_ranges(node : @cst.SyntaxNode, depth : Int) -> Unit {
  let indent = String::make(depth * 2, ' ')
  let range = node.text_range()
  println("\{indent}Node: [\{range.start().to_int()}, \{range.end().to_int()})")

  for child in node.children() {
    match child {
      @cst.SyntaxElement::Node(n) => print_ranges(n, depth + 1)
      @cst.SyntaxElement::Token(t) => {
        let token_indent = String::make((depth + 1) * 2, ' ')
        let r = t.text_range()
        println(
          "\{token_indent}Token \"\{t.text()}\": [\{r.start().to_int()}, \{r.end().to_int()})",
        )
      }
    }
  }
}