# setup tinytest for checkmate functionality
library("tinytest")
library("checkmate")
using("checkmate")

# ------ minimal term dataset fixture ------

d <- structure(
  data.frame(
    term = factor(
      c("water", "water", "aquifer", "aquifer", "nitrate")
    ),
    pub_id = factor(
      c("PubA", "PubB", "PubA", "PubC", "PubB")
    ),
    freq = c(10L, 3L, 5L, 8L, 2L)
  ),
  class = c("term", "data.frame")
)

# ------ simplify = TRUE (default) ------

# returns a character vector
out <- search_terms("water", data = d)
expect_true(is.character(out))

# returns only unique pub_ids
expect_equal(length(out), length(unique(out)))

# correct pub_ids matched
expect_true(all(c("PubA", "PubB") %in% out))
expect_false("PubC" %in% out)

# ordered by most frequent matching term first (PubA freq=10 before PubB freq=3)
expect_equal(out[1], "PubA")

# ------ simplify = FALSE ------

out_df <- search_terms("water", data = d, simplify = FALSE)
expect_true(is.data.frame(out_df))
expect_equal(colnames(out_df), c("term", "pub_id", "freq"))
expect_true(nrow(out_df) > 0L)

# sorted by decreasing frequency
expect_true(all(diff(out_df$freq) <= 0L))

# ------ ignore_case ------

out_upper <- search_terms("WATER", data = d, ignore_case = TRUE)
out_exact <- search_terms("WATER", data = d, ignore_case = FALSE)
expect_true(length(out_upper) > 0L)
expect_equal(length(out_exact), 0L)

# ------ frequency filtering ------

# low_freq excludes terms below threshold
out_low <- search_terms("water", data = d, low_freq = 5)
expect_false("PubB" %in% out_low) # PubB has freq=3, below threshold
expect_true("PubA" %in% out_low) # PubA has freq=10

# high_freq excludes terms above threshold
out_high <- search_terms("water", data = d, high_freq = 5)
expect_false("PubA" %in% out_high) # PubA has freq=10, above threshold
expect_true("PubB" %in% out_high) # PubB has freq=3

# ------ no matches returns empty result ------

expect_equal(length(search_terms("zzznomatch", data = d)), 0L)
expect_equal(nrow(search_terms("zzznomatch", data = d, simplify = FALSE)), 0L)

# ------ regex pattern ------

out_regex <- search_terms("wat|nit", data = d)
expect_true("PubA" %in% out_regex)
expect_true("PubB" %in% out_regex)

# ------ invalid arguments ------

expect_error(search_terms(NA_character_, data = d))
expect_error(search_terms("water", data = d, low_freq = 0))
expect_error(search_terms("water", data = d, low_freq = 5, high_freq = 3))
expect_error(search_terms("water", data = data.frame()))
