## load data
data(ExampleData.FittingLM, envir = environment())

test_that("input validation", {
  testthat::skip_on_cran()

  expect_error(fit_LMCurve("error"),
               "'object' should be of class 'data.frame' or 'RLum.Data.Curve'")
  expect_error(fit_LMCurve(data.frame()),
               "'object' cannot be an empty data.frame")
  expect_error(fit_LMCurve(iris[, 1, drop = FALSE]),
               "'object' should have 2 columns")
  expect_error(fit_LMCurve(set_RLum("RLum.Data.Curve")),
               "recordType should be 'RBR' or 'LM-OSL'")
  expect_error(fit_LMCurve(set_RLum("RLum.Data.Curve", recordType = "OSL")),
               "recordType should be 'RBR' or 'LM-OSL'")
  expect_error(fit_LMCurve(values.curve, object.bg = "error"),
               "'object.bg' should be of class 'data.frame' or 'RLum.Data.Curve'")
  expect_error(fit_LMCurve(set_RLum("RLum.Data.Curve", recordType = "LM-OSL"),
                           object.bg = values.curveBG),
               "'object' and 'object.bg' have different lengths")
  expect_error(fit_LMCurve(values.curve, object.bg = values.curveBG[, 1, drop = FALSE]),
               "'object.bg' should have 2 columns")
  expect_error(fit_LMCurve(values.curve, object.bg = values.curveBG,
                           bg.subtraction = "error"),
               "'bg.subtraction' should be one of 'polynomial', 'linear', 'channel'")
  expect_error(fit_LMCurve(values.curve, n.components = "error"),
               "'n.components' should be a single positive integer value")
  expect_error(fit_LMCurve(values.curve, input.dataType = "error"),
               "'input.dataType' should be one of 'LM' or 'pLM'")
  expect_error(fit_LMCurve(
    values.curve,
    object.bg = set_RLum("RLum.Data.Curve", data = as.matrix(values.curve), recordType = "OSL"),
    verbose = FALSE),
               "'recordType' for 'object.bg' should be 'RBR'")
  expect_error(fit_LMCurve(data.frame(NA, 1:5)),
               "After NA removal, nothing is left from the data set")
  expect_error(fit_LMCurve(values.curve[1:5, ]),
               "At least 6 data points are required to fit 3 components")

  ## warning for failed confint ...skip on windows because with R >= 4.2 is does not fail anymore
  # SW({
  # if (!grepl(pattern = "mingw", sessionInfo()$platform) && !grepl(pattern = "linux", sessionInfo()$platform))
  #   fit_LMCurve(values.curve, fit.calcError = TRUE)
  # })

  ## deprecated argument
  SW({
  expect_warning(fit_LMCurve(values = values.curve, fit.calcError = TRUE),
                 "'values' was deprecated in v1.2.0, use 'object' instead")
  expect_warning(fit_LMCurve(values.curve, values.bg = values.curveBG),
                 "'values.bg' was deprecated in v1.2.0, use 'object.bg' instead")
  })
})

test_that("snapshot tests", {
  testthat::skip_on_cran()

  snapshot.tolerance <- 1.5e-4

  SW({
  set.seed(1)
  fit <- fit_LMCurve(values.curve, object.bg = values.curveBG,
                     n.components = 3, log = "x",
                     method_control = list(
                         export.comp.contrib.matrix = TRUE),
                     start_values = data.frame(Im = c(170,25,400),
                                               xm = c(56,200,1500)))
  })
  expect_snapshot_RLum(fit, tolerance = snapshot.tolerance)

  SW({
  fit2 <- fit_LMCurve(values.curve,
                      object.bg = values.curveBG,
                      n.components = 3,
                      log = "x",
                      method_control = list(
                          export.comp.contrib.matrix = TRUE),
                      plot = FALSE)
  })
  expect_snapshot_RLum(fit2, tolerance = snapshot.tolerance)

  SW({
  expect_message(expect_warning(
      fit <- fit_LMCurve(values.curve, object.bg = values.curveBG,
                         n.components = 6, fit.method = "port"),
      "`fit.method = 'port'` is deprecated, fitting always occurs with the 'LM'"),
      "Error: Fitting failed, plot without fit produced")
  expect_equal(fit@data$component_matrix, NA)

  set.seed(1)
  expect_snapshot_RLum(fit_LMCurve(values.curve, object.bg = values.curveBG,
                                   method_control = list(
                                       export.comp.contrib.matrix = TRUE),
                                   plot.BG = TRUE, bg.subtraction = "linear"),
                       tolerance = snapshot.tolerance)

  suppressWarnings(
      expect_warning(fit_LMCurve(values.curve, object.bg = values.curveBG,
                                 n.components = 4, fit.calcError = TRUE),
                 "The computation of the parameter confidence intervals failed")
  )

  ## more coverage
  curveBG <- set_RLum("RLum.Data.Curve", data = as.matrix(values.curveBG), recordType = "RBR")
  expect_warning(fit_LMCurve(values.curve, curveBG, xlab = "s", ylab = "a.u.",
                             xlim = c(0, 4000), log = "xy"),
                 "'xlim' changed to avoid 0 values for log-scale")
  })
  expect_message(fit_LMCurve(values.curve[1:15, ], main = ""),
                 "Fitting failed, plot without fit produced")
  pdf(tempfile(), width = 1, height = 1)
  expect_message(fit_LMCurve(values.curve, verbose = FALSE),
                 "Figure margins too large or plot area too small")

  SW({
  skip_on_os("mac")
  expect_snapshot_RLum(fit_LMCurve(values.curve, object.bg = values.curveBG,
                                   xlim = c(0, 4000), ylim = c(0, 600), cex = 0.9,
                                   method_control = list(
                                       export.comp.contrib.matrix = TRUE),
                                   fit.calcError = TRUE),
                       tolerance = snapshot.tolerance)
  expect_snapshot_RLum(fit_LMCurve(values.curve, object.bg = values.curveBG,
                                   plot.BG = TRUE, input.dataType = "pLM",
                                   method_control = list(
                                       export.comp.contrib.matrix = TRUE),
                                   bg.subtraction = "channel"),
                       tolerance = snapshot.tolerance)
  })
})

test_that("graphical snapshot tests", {
  testthat::skip_on_cran()
  testthat::skip_if_not_installed("vdiffr")

  SW({
  vdiffr::expect_doppelganger("default",
                              fit_LMCurve(values.curve))
  vdiffr::expect_doppelganger("logy",
                              fit_LMCurve(values.curve, log = "y",
                                          legend.pos = "topleft",
                                          plot.contribution = FALSE))
  })
})

test_that("regression tests", {
  testthat::skip_on_cran()

  ## issue 755
  expect_silent(fit_LMCurve(values.curve, log = "y", verbose = FALSE))
  expect_silent(fit_LMCurve(values.curve, log = "xy", verbose = FALSE,
                            input.dataType = "pLM"))

  ## issue 757
  values.na <- values.curve
  values.na[c(5, 25), ] <- NA
  expect_silent(fit_LMCurve(values.na, verbose = FALSE))
  expect_silent(fit_LMCurve(values.na, object.bg = values.curveBG, verbose = FALSE))

  ## issue 763
  values.na <- values.curveBG
  values.na[c(5, 25), ] <- NA
  expect_silent(fit_LMCurve(values.curve, object.bg = values.na, verbose = FALSE))
})
