
test_that("different versions required", {
  setup_fake_gh_app()
  setup_fake_apps()

  lib <- withr::local_tempdir()
  p <- new_pkg_installation_proposal(
    c("r-lib/crayon", "crayon"),
    config = list(library = lib)
  )

  suppressMessages(p$solve())
  expect_snapshot(
    error = TRUE,
    p$stop_for_solution_error(),
    # need to sort this, otherwise it is not deterministic
    transform = function(x) {
      x[-1] <- sort(x[-1], decreasing = TRUE)
      x
    }
  )
})

test_that("direct CRAN conflicts with downstream GH dep", {

  gh <- list(
    users = list(
      "r-lib" = list(
         repos = list(
           foo = list(
             commits = list(
               list(
                 sha = "b69f0b34da3b538a666c02944d67ebae9535488fa9d29a010a79980822b56780",
                 branch = "main",
                 tag = "HEAD",
                 files = list(
                   DESCRIPTION = "Package: foo\nVersion: 1.0.0\nImports: crayon\nRemotes: r-lib/crayon\n",
                   NAMESPACE = ""
                 )
               )
             )
           ),
           crayon = list(
             commits = list(
               list(
                 sha = "09ec8a1bbab45ba6a54f896f721fdf00798559ef71852063ea4934d9656101d0",
                 branch = "main",
                 tag = "HEAD",
                 files = list(
                   DESCRIPTION = gh_app_desc("crayon"),
                   NAMESPACE = ""
                 )
               )
             )
           )
         )
       )
    )
  )

  fake_gh <- webfakes::local_app_process(
    gh_app(gh)
  )
  withr::local_envvar(R_PKG_GITHUB_API_URL = fake_gh$url())
  setup_fake_apps()

  lib <- withr::local_tempdir()
  p <- new_pkg_installation_proposal(
    c("r-lib/foo", "crayon"),
    config = list(library = lib)
  )

  suppressMessages(p$solve())
  expect_snapshot(
    error = TRUE,
    p$stop_for_solution_error()
  )
})

test_that("no required version", {
  repo <- dcf("
    Package: pkg1
    Depends: pkg2 (>= 2.0.0)

    Package: pkg2
    Version: 1.0.0
  ")
  setup_fake_apps(cran_repo = repo)

  lib <- withr::local_tempdir()
  p <- new_pkg_installation_proposal("pkg1", config = list(library = lib))

  suppressMessages(p$solve())
  expect_snapshot(error = TRUE, p$stop_for_solution_error())
})

test_that("failed resolution", {
  setup_fake_apps()
  setup_fake_gh_app()

  lib <- withr::local_tempdir()
  p1 <- new_pkg_installation_proposal("SDF", config = list(library = lib))
  suppressMessages(p1$solve())
  expect_snapshot(error = TRUE, p1$stop_for_solution_error())

  p2 <- new_pkg_installation_proposal("SDF/SDF", config = list(library = lib))
  suppressMessages(p2$solve())
  expect_snapshot(error = TRUE, p2$stop_for_solution_error())
})

test_that("ruled out direct dep", {
  # I.e. there are multiple versions, the newer version is ruled out
  # for the current R version, but the older vresion is fine.

  # pkgcache::cran_app cannot seem to do this with a single repo
  repo1 <- dcf("
    Package: pkg1
    Version: 1.0.0
  ")

  repo2 <- dcf("
    Package: pkg1
    Version: 1.0.1
    Depends: R (>= 20000.0.0)
  ")

  fake1 <- webfakes::new_app_process(cran_app(repo1))
  fake2 <- webfakes::new_app_process(cran_app(repo2))
  withr::local_options(repos = c(CRAN = fake1$url(), X = fake2$url()))

  lib <- tempfile()
  lock <- tempfile()
  on.exit(unlink(c(lib, lock), recursive = TRUE), add = TRUE)

  p <- suppressMessages(new_pkg_installation_proposal(
    c("pkg1"),
    config = list(
      dependencies = TRUE,
      library = lib
    )
  ))
  suppressMessages(p$solve())
  expect_equal(p$get_solution()$data$version, "1.0.0")
})
