// =============================================================================
// Selector Index Benchmarks
// =============================================================================
// Compare indexed vs non-indexed selector matching

///|
fn create_test_stylesheet(num_rules : Int) -> Stylesheet {
  let stylesheet = Stylesheet::new(Author)
  // Create various selector patterns using helper functions
  for i = 0; i < num_rules; i = i + 1 {
    let idx = i % 6
    let selector = match idx {
      0 => {
        // ID selector: #item-N
        let compound = @selector.CompoundSelector::from_id(
          "item-" + i.to_string(),
        )
        @selector.ComplexSelector::simple(compound)
      }
      1 | 2 => {
        // Class selector: .class-N
        let compound = @selector.CompoundSelector::from_class(
          "class-" + (i % 50).to_string(),
        )
        @selector.ComplexSelector::simple(compound)
      }
      3 | 4 => {
        // Tag selector: div
        let compound = @selector.CompoundSelector::from_type("div")
        @selector.ComplexSelector::simple(compound)
      }
      _ => {
        // Universal: *
        let compound = @selector.CompoundSelector::universal()
        @selector.ComplexSelector::simple(compound)
      }
    }
    let decls : Array[Declaration] = [
      {
        property: "color",
        value: Value("red"),
        origin: Author,
        importance: Normal,
        specificity: { a: 0, b: 0, c: 0 },
        source_order: 0,
      },
    ]
    stylesheet.add_rule(selector.to_string(), selector, decls)
  }
  stylesheet
}

///|
fn create_test_element(
  id : String,
  classes : Array[String],
) -> @selector.Element {
  let mut elem = @selector.Element::new("div")
  elem = elem.set_id(id)
  for cls in classes {
    elem = elem.add_class(cls)
  }
  elem
}

///|
test "bench_selector_match_non_indexed_100" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(100)
  let elem = create_test_element("item-5", ["class-10", "container"])
  b.bench(name="match_non_idx_100", fn() {
    b.keep(stylesheet.match_element(elem))
  })
}

///|
test "bench_selector_match_indexed_100" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(100)
  let indexed = IndexedStylesheet::new(stylesheet)
  let elem = create_test_element("item-5", ["class-10", "container"])
  b.bench(name="match_indexed_100", fn() { b.keep(indexed.match_element(elem)) })
}

///|
test "bench_selector_match_non_indexed_500" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(500)
  let elem = create_test_element("item-25", ["class-20", "container"])
  b.bench(name="match_non_idx_500", fn() {
    b.keep(stylesheet.match_element(elem))
  })
}

///|
test "bench_selector_match_indexed_500" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(500)
  let indexed = IndexedStylesheet::new(stylesheet)
  let elem = create_test_element("item-25", ["class-20", "container"])
  b.bench(name="match_indexed_500", fn() { b.keep(indexed.match_element(elem)) })
}

///|
test "bench_selector_match_non_indexed_1000" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(1000)
  let elem = create_test_element("item-100", ["class-30", "container", "active"])
  b.bench(name="match_non_idx_1k", fn() {
    b.keep(stylesheet.match_element(elem))
  })
}

///|
test "bench_selector_match_indexed_1000" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(1000)
  let indexed = IndexedStylesheet::new(stylesheet)
  let elem = create_test_element("item-100", ["class-30", "container", "active"])
  b.bench(name="match_indexed_1k", fn() { b.keep(indexed.match_element(elem)) })
}

///|
test "bench_cascade_multiple_elements_non_indexed" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(200)
  let stylesheets = [stylesheet]
  let elements : Array[@selector.Element] = []
  for i = 0; i < 100; i = i + 1 {
    elements.push(
      create_test_element("item-" + i.to_string(), [
        "class-" + (i % 50).to_string(),
      ]),
    )
  }
  b.bench(name="cascade_non_idx", fn() {
    for elem in elements {
      b.keep(cascade_element(elem, stylesheets, []))
    }
  })
}

///|
test "bench_cascade_multiple_elements_indexed" (b : @bench.T) {
  let stylesheet = create_test_stylesheet(200)
  let indexed = IndexedStylesheet::new(stylesheet)
  let stylesheets = [indexed]
  let elements : Array[@selector.Element] = []
  for i = 0; i < 100; i = i + 1 {
    elements.push(
      create_test_element("item-" + i.to_string(), [
        "class-" + (i % 50).to_string(),
      ]),
    )
  }
  b.bench(name="cascade_indexed", fn() {
    for elem in elements {
      b.keep(cascade_element_indexed(elem, stylesheets, [], None))
    }
  })
}