.runThisTest <- Sys.getenv("RunAllinsightTests") == "yes"

if (.runThisTest) {
  if (suppressWarnings(requiet("testthat") &&
    requiet("insight") &&
    requiet("brms"))) {
    # Model fitting -----------------------------------------------------------

    m1 <- suppressWarnings(insight::download_model("brms_mixed_6"))
    m2 <- insight::download_model("brms_mv_4")
    m3 <- insight::download_model("brms_2")
    m4 <- insight::download_model("brms_zi_3")
    m5 <- insight::download_model("brms_mv_5")
    m6 <- insight::download_model("brms_corr_re1")
    m7 <- suppressWarnings(insight::download_model("brms_mixed_8"))
    m8 <- insight::download_model("brms_ordinal_1")

    # Tests -------------------------------------------------------------------
    test_that("get_predicted.brmsfit: ordinal dv", {
      skip_if_not_installed("bayestestR")

      pred1 <- get_predicted(m8, ci = 0.95)
      pred2 <- get_predicted(m8, ci_method = "hdi", ci = 0.95)
      expect_true(inherits(pred1, "get_predicted"))
      expect_true(inherits(pred1, "data.frame"))
      expect_true(all(c("Row", "Response") %in% colnames(pred1)))

      # ci_method changes intervals but not se or predicted
      pred1 <- data.frame(pred1)
      pred2 <- data.frame(pred2)
      expect_equal(pred1$Row, pred2$Row)
      expect_equal(pred1$Response, pred2$Response)
      expect_equal(pred1$Predicted, pred2$Predicted)
      expect_equal(pred1$SE, pred2$SE)
      expect_false(mean(pred1$CI_low == pred2$CI_low) > 0.1) # most CI bounds are different
      expect_false(mean(pred1$CI_high == pred2$CI_high) > 0.1) # most CI bounds are different

      # compare to manual predictions
      pred3 <- get_predicted(m8, centrality_function = stats::median, ci = 0.95)
      manual <- rstantools::posterior_epred(m8)
      manual <- apply(manual[, , 1], 2, median)
      expect_equal(pred3$Predicted[1:32], manual)
      manual <- rstantools::posterior_epred(m8)
      manual <- apply(manual[, , 1], 2, mean)
      expect_equal(pred1$Predicted[1:32], manual)
    })

    test_that("find_statistic", {
      expect_null(find_statistic(m1))
      expect_null(find_statistic(m2))
      expect_null(find_statistic(m3))
      expect_null(find_statistic(m4))
      expect_null(find_statistic(m5))
    })

    test_that("n_parameters", {
      expect_equal(n_parameters(m1), 65)
      expect_equal(n_parameters(m1, effects = "fixed"), 5)
    })

    test_that("model_info", {
      expect_true(model_info(m3)$is_trial)
      expect_true(model_info(m5)[[1]]$is_zero_inflated)
      expect_true(model_info(m5)[[1]]$is_bayesian)
    })

    test_that("clean_names", {
      expect_identical(
        clean_names(m1),
        c("count", "Age", "Base", "Trt", "patient")
      )
      expect_identical(
        clean_names(m2),
        c(
          "Sepal.Length",
          "Sepal.Width",
          "Petal.Length",
          "Species"
        )
      )
      expect_identical(clean_names(m3), c("r", "n", "treat", "c2"))
      expect_identical(
        clean_names(m4),
        c("count", "child", "camper", "persons")
      )
      expect_identical(
        clean_names(m5),
        c(
          "count",
          "count2",
          "child",
          "camper",
          "persons",
          "livebait"
        )
      )
    })


    test_that("find_predictors", {
      expect_identical(find_predictors(m1), list(conditional = c("Age", "Base", "Trt")))
      expect_identical(
        find_predictors(m1, flatten = TRUE),
        c("Age", "Base", "Trt")
      )
      expect_identical(
        find_predictors(m1, effects = "all", component = "all"),
        list(
          conditional = c("Age", "Base", "Trt"),
          random = "patient"
        )
      )
      expect_identical(
        find_predictors(
          m1,
          effects = "all",
          component = "all",
          flatten = TRUE
        ),
        c("Age", "Base", "Trt", "patient")
      )

      expect_identical(
        find_predictors(m2),
        list(
          SepalLength = list(conditional = c(
            "Petal.Length", "Sepal.Width", "Species"
          )),
          SepalWidth = list(conditional = "Species")
        )
      )

      expect_identical(
        find_predictors(m2, flatten = TRUE),
        c("Petal.Length", "Sepal.Width", "Species")
      )
      expect_identical(find_predictors(m3), list(conditional = c("treat", "c2")))
      expect_identical(
        find_predictors(m4),
        list(
          conditional = c("child", "camper"),
          zero_inflated = c("child", "camper")
        )
      )
      expect_identical(
        find_predictors(m4, effects = "random"),
        list(random = "persons", zero_inflated_random = "persons")
      )
      expect_identical(find_predictors(m4, flatten = TRUE), c("child", "camper"))

      expect_identical(
        find_predictors(m5),
        list(
          count = list(
            conditional = c("child", "camper"),
            zero_inflated = "camper"
          ),
          count2 = list(
            conditional = c("child", "livebait"),
            zero_inflated = "child"
          )
        )
      )
    })

    test_that("find_response", {
      expect_equal(find_response(m1, combine = TRUE), "count")
      expect_equal(
        find_response(m2, combine = TRUE),
        c(SepalLength = "Sepal.Length", SepalWidth = "Sepal.Width")
      )
      expect_equal(find_response(m3, combine = TRUE), c("r", "n"))
      expect_equal(find_response(m1, combine = FALSE), "count")
      expect_equal(
        find_response(m2, combine = FALSE),
        c(SepalLength = "Sepal.Length", SepalWidth = "Sepal.Width")
      )
      expect_equal(find_response(m3, combine = FALSE), c("r", "n"))
      expect_equal(find_response(m4, combine = FALSE), "count")
      expect_equal(
        find_response(m5, combine = TRUE),
        c(count = "count", count2 = "count2")
      )
    })

    test_that("get_response", {
      expect_length(get_response(m1), 236)
      expect_equal(ncol(get_response(m2)), 2)
      expect_equal(
        colnames(get_response(m2)),
        c("Sepal.Length", "Sepal.Width")
      )
      expect_equal(ncol(get_response(m3)), 2)
      expect_equal(colnames(get_response(m3)), c("r", "n"))
      expect_length(get_response(m4), 250)
      expect_equal(colnames(get_response(m5)), c("count", "count2"))
    })

    test_that("find_variables", {
      expect_identical(
        find_variables(m1),
        list(
          response = "count",
          conditional = c("Age", "Base", "Trt"),
          random = "patient"
        )
      )
      expect_identical(
        find_variables(m6),
        list(
          response = "y",
          conditional = "x",
          random = "id",
          sigma = "x",
          sigma_random = "id"
        )
      )
      expect_identical(
        find_variables(m1, effects = "fixed"),
        list(
          response = "count",
          conditional = c("Age", "Base", "Trt")
        )
      )
      expect_null(find_variables(m1, component = "zi"))

      expect_identical(
        find_variables(m2),
        list(
          response = c(SepalLength = "Sepal.Length", SepalWidth = "Sepal.Width"),
          SepalLength = list(conditional = c(
            "Petal.Length", "Sepal.Width", "Species"
          )),
          SepalWidth = list(conditional = "Species")
        )
      )

      expect_identical(
        find_variables(m2, flatten = TRUE),
        c(
          "Sepal.Length",
          "Sepal.Width",
          "Petal.Length",
          "Species"
        )
      )
      expect_identical(find_variables(m3), list(
        response = c("r", "n"),
        conditional = c("treat", "c2")
      ))

      expect_identical(
        find_variables(m4),
        list(
          response = "count",
          conditional = c("child", "camper"),
          random = "persons",
          zero_inflated = c("child", "camper"),
          zero_inflated_random = "persons"
        )
      )

      expect_identical(
        find_variables(m4, flatten = TRUE),
        c("count", "child", "camper", "persons")
      )
    })

    test_that("n_obs", {
      expect_equal(n_obs(m1), 236)
      expect_equal(n_obs(m2), 150)
      expect_equal(n_obs(m3), 10)
      expect_equal(n_obs(m4), 250)
      expect_equal(n_obs(m5), 250)
    })


    test_that("find_random", {
      expect_equal(find_random(m5), list(
        count = list(
          random = "persons",
          zero_inflated_random = "persons"
        ),
        count2 = list(
          random = "persons",
          zero_inflated_random = "persons"
        )
      ))
      expect_equal(find_random(m5, flatten = TRUE), "persons")
      expect_equal(find_random(m6, flatten = TRUE), "id")
    })


    test_that("get_random", {
      zinb <- get_data(m4)
      expect_equal(get_random(m4), zinb[, "persons", drop = FALSE])
    })


    test_that("get_data", {
      d <- get_data(m6)
      expect_equal(nrow(d), 200)
      expect_equal(ncol(d), 3)
    })


    test_that("find_paramaters", {
      expect_equal(
        find_parameters(m1),
        list(
          conditional = c(
            "b_Intercept",
            "b_Age",
            "b_Base",
            "b_Trt1",
            "b_Base:Trt1"
          ),
          random = c(sprintf("r_patient[%i,Intercept]", 1:59), "sd_patient__Intercept")
        )
      )

      expect_equal(
        find_parameters(m2),
        structure(
          list(
            SepalLength = list(
              conditional = c(
                "b_SepalLength_Intercept",
                "b_SepalLength_Petal.Length",
                "b_SepalLength_Sepal.Width",
                "b_SepalLength_Speciesversicolor",
                "b_SepalLength_Speciesvirginica"
              ),
              sigma = "sigma_SepalLength"
            ),
            SepalWidth = list(
              conditional = c(
                "b_SepalWidth_Intercept",
                "b_SepalWidth_Speciesversicolor",
                "b_SepalWidth_Speciesvirginica"
              ),
              sigma = "sigma_SepalWidth"
            )
          ),
          "is_mv" = "1"
        )
      )

      expect_equal(
        find_parameters(m4),
        list(
          conditional = c("b_Intercept", "b_child", "b_camper"),
          random = c(sprintf("r_persons[%i,Intercept]", 1:4), "sd_persons__Intercept"),
          zero_inflated = c("b_zi_Intercept", "b_zi_child", "b_zi_camper"),
          zero_inflated_random = c(sprintf("r_persons__zi[%i,Intercept]", 1:4), "sd_persons__zi_Intercept")
        )
      )

      expect_equal(
        find_parameters(m5, effects = "all"),
        structure(
          list(
            count = list(
              conditional = c("b_count_Intercept", "b_count_child", "b_count_camper"),
              random = c(sprintf("r_persons__count[%i,Intercept]", 1:4), "sd_persons__count_Intercept"),
              zero_inflated = c("b_zi_count_Intercept", "b_zi_count_camper"),
              zero_inflated_random = c(sprintf("r_persons__zi_count[%i,Intercept]", 1:4), "sd_persons__zi_count_Intercept")
            ),
            count2 = list(
              conditional = c(
                "b_count2_Intercept",
                "b_count2_child",
                "b_count2_livebait"
              ),
              random = c(sprintf("r_persons__count2[%i,Intercept]", 1:4), "sd_persons__count2_Intercept"),
              zero_inflated = c("b_zi_count2_Intercept", "b_zi_count2_child"),
              zero_inflated_random = c(sprintf("r_persons__zi_count2[%i,Intercept]", 1:4), "sd_persons__zi_count2_Intercept")
            )
          ),
          "is_mv" = "1"
        )
      )
    })

    test_that("find_paramaters", {
      expect_equal(
        colnames(get_parameters(m4)),
        c(
          "b_Intercept",
          "b_child",
          "b_camper",
          "b_zi_Intercept",
          "b_zi_child",
          "b_zi_camper"
        )
      )
      expect_equal(
        colnames(get_parameters(m4, component = "zi")),
        c("b_zi_Intercept", "b_zi_child", "b_zi_camper")
      )
      expect_equal(
        colnames(get_parameters(m4, effects = "all")),
        c(
          "b_Intercept", "b_child", "b_camper", "r_persons[1,Intercept]",
          "r_persons[2,Intercept]", "r_persons[3,Intercept]", "r_persons[4,Intercept]",
          "sd_persons__Intercept", "b_zi_Intercept", "b_zi_child", "b_zi_camper",
          "r_persons__zi[1,Intercept]", "r_persons__zi[2,Intercept]", "r_persons__zi[3,Intercept]",
          "r_persons__zi[4,Intercept]", "sd_persons__zi_Intercept"
        )
      )
      expect_equal(
        colnames(get_parameters(m4, effects = "random", component = "conditional")),
        c(
          "r_persons[1,Intercept]", "r_persons[2,Intercept]", "r_persons[3,Intercept]",
          "r_persons[4,Intercept]", "sd_persons__Intercept"
        )
      )
      expect_equal(
        colnames(get_parameters(m5, effects = "random", component = "conditional")),
        c(
          "r_persons__count[1,Intercept]", "r_persons__count[2,Intercept]",
          "r_persons__count[3,Intercept]", "r_persons__count[4,Intercept]",
          "sd_persons__count_Intercept", "r_persons__count2[1,Intercept]",
          "r_persons__count2[2,Intercept]", "r_persons__count2[3,Intercept]",
          "r_persons__count2[4,Intercept]", "sd_persons__count2_Intercept"
        )
      )

      expect_equal(
        colnames(get_parameters(m5, effects = "all", component = "all")),
        c(
          "b_count_Intercept", "b_count_child", "b_count_camper", "r_persons__count[1,Intercept]",
          "r_persons__count[2,Intercept]", "r_persons__count[3,Intercept]",
          "r_persons__count[4,Intercept]", "sd_persons__count_Intercept",
          "b_zi_count_Intercept", "b_zi_count_camper", "r_persons__zi_count[1,Intercept]",
          "r_persons__zi_count[2,Intercept]", "r_persons__zi_count[3,Intercept]",
          "r_persons__zi_count[4,Intercept]", "sd_persons__zi_count_Intercept",
          "b_count2_Intercept", "b_count2_child", "b_count2_livebait",
          "r_persons__count2[1,Intercept]", "r_persons__count2[2,Intercept]",
          "r_persons__count2[3,Intercept]", "r_persons__count2[4,Intercept]",
          "sd_persons__count2_Intercept", "b_zi_count2_Intercept", "b_zi_count2_child",
          "r_persons__zi_count2[1,Intercept]", "r_persons__zi_count2[2,Intercept]",
          "r_persons__zi_count2[3,Intercept]", "r_persons__zi_count2[4,Intercept]",
          "sd_persons__zi_count2_Intercept"
        )
      )
    })

    test_that("linkfun", {
      expect_false(is.null(link_function(m1)))
      expect_length(link_function(m2), 2)
      expect_false(is.null(link_function(m3)))
      expect_false(is.null(link_function(m4)))
      expect_length(link_function(m5), 2)
    })

    test_that("linkinv", {
      expect_false(is.null(link_inverse(m1)))
      expect_length(link_inverse(m2), 2)
      expect_false(is.null(link_inverse(m3)))
      expect_false(is.null(link_inverse(m4)))
      expect_length(link_inverse(m2), 2)
    })

    test_that("is_multivariate", {
      expect_false(is_multivariate(m1))
      expect_true(is_multivariate(m2))
      expect_false(is_multivariate(m3))
      expect_false(is_multivariate(m4))
      expect_true(is_multivariate(m5))
    })

    test_that("find_terms", {
      expect_equal(
        find_terms(m2),
        list(
          SepalLength = list(
            response = "Sepal.Length",
            conditional = c("Petal.Length", "Sepal.Width", "Species")
          ),
          SepalWidth = list(
            response = "Sepal.Width",
            conditional = "Species"
          )
        )
      )
    })

    test_that("find_algorithm", {
      expect_equal(
        find_algorithm(m1),
        list(
          algorithm = "sampling",
          chains = 1,
          iterations = 500,
          warmup = 250
        )
      )
    })


    test_that("get_priors", {
      expect_equal(
        get_priors(m7),
        data.frame(
          Parameter = c(
            "b_Intercept", "b_Age", "b_Base", "b_Trt1", "b_Base:Trt1",
            "sd_patient__Intercept", "sd_patient__Age",
            "cor_patient__Intercept__Age"
          ),
          Distribution = c(
            "student_t", "student_t", "student_t",
            "student_t", "student_t", "cauchy", "cauchy", "lkj"
          ),
          Location = c(1.4, 0, 0, 0, 0, NA, NA, 1),
          Scale = c(2.5, 10, 10, 10, 10, NA, NA, NA),
          df = c(3, 5, 5, 5, 5, NA, NA, NA),
          stringsAsFactors = FALSE
        ),
        ignore_attr = TRUE
      )
      expect_equal(
        get_priors(m3),
        data.frame(
          Parameter = c("b_Intercept", "b_treat1", "b_c2", "b_treat1:c2"),
          Distribution = c("student_t", "uniform", "uniform", "uniform"),
          Location = c(0, NA, NA, NA),
          Scale = c(2.5, NA, NA, NA),
          df = c(3, NA, NA, NA),
          stringsAsFactors = FALSE
        ),
        ignore_attr = TRUE
      )
    })

    test_that("Issue #645", {
      # apparently BH is required to fit these brms models
      skip_if_not_installed("BH")

      void <- suppressMessages(suppressWarnings(capture.output(
        mod <- brm(
          silent = 2,
          data = mtcars,
          family = cumulative(probit),
          formula = bf(
            cyl ~ 1 + mpg + drat + gearnl,
            gearnl ~ 0 + (1 | gear),
            nl = TRUE
          )
        )
      )))

      p <- find_predictors(mod, flatten = TRUE)
      d <- get_data(mod)
      expect_true("gear" %in% p)
      expect_true("gear" %in% colnames(d))
    })

    test_that("clean_parameters", {
      expect_equal(
        clean_parameters(m4),
        structure(
          list(
            Parameter = c(
              "b_Intercept",
              "b_child",
              "b_camper",
              "r_persons[1,Intercept]",
              "r_persons[2,Intercept]",
              "r_persons[3,Intercept]",
              "r_persons[4,Intercept]",
              "sd_persons__Intercept",
              "b_zi_Intercept",
              "b_zi_child",
              "b_zi_camper",
              "r_persons__zi[1,Intercept]",
              "r_persons__zi[2,Intercept]",
              "r_persons__zi[3,Intercept]",
              "r_persons__zi[4,Intercept]",
              "sd_persons__zi_Intercept"
            ),
            Effects = c(
              "fixed",
              "fixed",
              "fixed",
              "random",
              "random",
              "random",
              "random",
              "random",
              "fixed",
              "fixed",
              "fixed",
              "random",
              "random",
              "random",
              "random",
              "random"
            ),
            Component = c(
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated"
            ),
            Group = c(
              "",
              "",
              "",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "SD/Cor: persons",
              "",
              "",
              "",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "SD/Cor: persons"
            ),
            Cleaned_Parameter = c(
              "(Intercept)",
              "child",
              "camper",
              "persons.1",
              "persons.2",
              "persons.3",
              "persons.4",
              "(Intercept)",
              "(Intercept)",
              "child",
              "camper",
              "persons.1",
              "persons.2",
              "persons.3",
              "persons.4",
              "(Intercept)"
            )
          ),
          class = c("clean_parameters", "data.frame"),
          row.names = c(
            NA,
            -16L
          )
        ),
        ignore_attr = TRUE
      )

      expect_equal(
        clean_parameters(m5),
        structure(
          list(
            Parameter = c(
              "b_count_Intercept",
              "b_count_child",
              "b_count_camper",
              "b_count2_Intercept",
              "b_count2_child",
              "b_count2_livebait",
              "r_persons__count[1,Intercept]",
              "r_persons__count[2,Intercept]",
              "r_persons__count[3,Intercept]",
              "r_persons__count[4,Intercept]",
              "sd_persons__count_Intercept",
              "r_persons__count2[1,Intercept]",
              "r_persons__count2[2,Intercept]",
              "r_persons__count2[3,Intercept]",
              "r_persons__count2[4,Intercept]",
              "sd_persons__count2_Intercept",
              "b_zi_count_Intercept",
              "b_zi_count_camper",
              "b_zi_count2_Intercept",
              "b_zi_count2_child",
              "r_persons__zi_count[1,Intercept]",
              "r_persons__zi_count[2,Intercept]",
              "r_persons__zi_count[3,Intercept]",
              "r_persons__zi_count[4,Intercept]",
              "sd_persons__zi_count_Intercept",
              "r_persons__zi_count2[1,Intercept]",
              "r_persons__zi_count2[2,Intercept]",
              "r_persons__zi_count2[3,Intercept]",
              "r_persons__zi_count2[4,Intercept]",
              "sd_persons__zi_count2_Intercept"
            ),
            Effects = c(
              "fixed",
              "fixed",
              "fixed",
              "fixed",
              "fixed",
              "fixed",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "fixed",
              "fixed",
              "fixed",
              "fixed",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random",
              "random"
            ),
            Component = c(
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "conditional",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated",
              "zero_inflated"
            ),
            Group = c(
              "",
              "",
              "",
              "",
              "",
              "",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "SD/Cor: persons",
              "Intercept: persons2",
              "Intercept: persons2",
              "Intercept: persons2",
              "Intercept: persons2",
              "SD/Cor: persons",
              "",
              "",
              "",
              "",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "Intercept: persons",
              "SD/Cor: persons",
              "Intercept: persons2",
              "Intercept: persons2",
              "Intercept: persons2",
              "Intercept: persons2",
              "SD/Cor: persons"
            ),
            Response = c(
              "count",
              "count",
              "count",
              "count2",
              "count2",
              "count2",
              "count",
              "count",
              "count",
              "count",
              "count",
              "count2",
              "count2",
              "count2",
              "count2",
              "count2",
              "count",
              "count",
              "count2",
              "count2",
              "count",
              "count",
              "count",
              "count",
              "count",
              "count2",
              "count2",
              "count2",
              "count2",
              "count2"
            ),
            Cleaned_Parameter = c(
              "(Intercept)",
              "child",
              "camper",
              "(Intercept)",
              "child",
              "livebait",
              "persons.1",
              "persons.2",
              "persons.3",
              "persons.4",
              "count_Intercept",
              "persons2.1",
              "persons2.2",
              "persons2.3",
              "persons2.4",
              "count2_Intercept",
              "(Intercept)",
              "camper",
              "(Intercept)",
              "child",
              "persons.1",
              "persons.2",
              "persons.3",
              "persons.4",
              "zi_count_Intercept",
              "persons2.1",
              "persons2.2",
              "persons2.3",
              "persons2.4",
              "zi_count2_Intercept"
            )
          ),
          class = c("clean_parameters", "data.frame"),
          row.names = c(NA, -30L)
        ),
        ignore_attr = TRUE
      )
    })
  }
}
