# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

library(dplyr, warn.conflicts = FALSE)
library(stringr)

skip_if_not_available("acero")

tbl <- example_data

test_that("Empty select returns no columns", {
  compare_dplyr_binding(
    .input %>% select() %>% collect(),
    tbl
  )
})

test_that("Empty select still includes the group_by columns", {
  expect_message(
    compare_dplyr_binding(
      .input %>% group_by(chr) %>% select() %>% collect(),
      tbl
    ),
    "Adding missing grouping variables"
  )
})

test_that("Missing grouping columns are added to the beginning of the list", {
  expect_message(
    compare_dplyr_binding(
      .input %>% group_by(chr) %>% select(int) %>% collect(),
      tbl
    ),
    "Adding missing grouping variables"
  )
})

test_that("select/rename/rename_with", {
  compare_dplyr_binding(
    .input %>%
      select(string = chr, int) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      rename(string = chr) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      rename(strng = chr) %>%
      rename(other = strng) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      rename_with(
        ~ paste0(.x, "_suffix"),
        .cols = c("int", "chr")
      ) %>%
      collect(),
    tbl
  )
})

test_that("select/rename/rename_with using selection helpers", {
  compare_dplyr_binding(
    .input %>%
      select(everything()) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      select(any_of(c("int", "not_a_column", "lgl"))) %>%
      collect(),
    tbl
  )

  compare_dplyr_binding(
    .input %>%
      select(starts_with("d")) %>%
      collect(),
    tbl
  )

  compare_dplyr_binding(
    .input %>%
      select(where(is.numeric)) %>%
      collect(),
    tbl
  )

  compare_dplyr_binding(
    .input %>%
      rename_with(toupper) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      rename_with(toupper, .cols = c()) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      rename_with(
        ~ paste0(.x, "_suffix"),
        .cols = starts_with("d")
      ) %>%
      collect(),
    tbl
  )
})

test_that("filtering with rename", {
  compare_dplyr_binding(
    .input %>%
      filter(chr == "b") %>%
      select(string = chr, int) %>%
      collect(),
    tbl
  )
  compare_dplyr_binding(
    .input %>%
      select(string = chr, int) %>%
      filter(string == "b") %>%
      collect(),
    tbl
  )
})

test_that("relocate", {
  df <- tibble(a = 1, b = 1, c = 1, d = "a", e = "a", f = "a")
  compare_dplyr_binding(
    .input %>% relocate(f) %>% collect(),
    df,
  )
  compare_dplyr_binding(
    .input %>% relocate(a, .after = c) %>% collect(),
    df,
  )
  compare_dplyr_binding(
    .input %>% relocate(f, .before = b) %>% collect(),
    df,
  )
  compare_dplyr_binding(
    .input %>% relocate(a, .after = last_col()) %>% collect(),
    df,
  )
  compare_dplyr_binding(
    .input %>% relocate(ff = f) %>% collect(),
    df,
  )
})

test_that("relocate with selection helpers", {
  df <- tibble(a = 1, b = 1, c = 1, d = "a", e = "a", f = "a")
  compare_dplyr_binding(
    .input %>% relocate(any_of(c("a", "e", "i", "o", "u"))) %>% collect(),
    df
  )
  compare_dplyr_binding(
    .input %>% relocate(where(is.character)) %>% collect(),
    df
  )
  compare_dplyr_binding(
    .input %>% relocate(a, b, c, .after = where(is.character)) %>% collect(),
    df
  )
  compare_dplyr_binding(
    .input %>% relocate(d, e, f, .before = where(is.numeric)) %>% collect(),
    df
  )
  # works after other dplyr verbs
  compare_dplyr_binding(
    .input %>%
      mutate(c = as.character(c)) %>%
      relocate(d, e, f, .after = where(is.numeric)) %>%
      collect(),
    df
  )
})

test_that("multiple select/rename and group_by", {
  compare_dplyr_binding(
    .input %>%
      group_by(chr) %>%
      rename(string = chr, dub = dbl2) %>%
      rename(chr_actually = string) %>%
      collect(),
    tbl
  )

  compare_dplyr_binding(
    .input %>%
      group_by(chr) %>%
      select(string = chr, dub = dbl2) %>%
      rename(chr_actually = string) %>%
      collect(),
    tbl
  )

  compare_dplyr_binding(
    .input %>%
      group_by(chr) %>%
      rename(string = chr, dub = dbl2) %>%
      select(chr_actually = string) %>%
      collect(),
    tbl
  )
})
