# Integration Tests Using Examples
#
# These tests run the example scripts to validate end-to-end functionality.
# Set RUN_INTEGRATION_TESTS=TRUE to enable (skipped by default).
# Set USE_STARBURST=TRUE to test with AWS (otherwise tests local execution).
#
# skip_if_no_integration() is defined in helper-aws.R (shared across test files).

# Helper to get package root directory (tests run from tests/testthat/)
get_pkg_root <- function() {
  if (basename(getwd()) == "testthat") {
    normalizePath("../..")
  } else if (file.exists("tests/testthat")) {
    getwd()
  } else {
    stop("Cannot determine package root")
  }
}

test_that("Monte Carlo example runs locally", {
  skip_if_no_integration()

  pkg_root <- get_pkg_root()

  # Run example without staRburst (run from pkg_root so results write there)
  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(USE_STARBURST = "FALSE"),
      system2(
        "Rscript",
        args = c("examples/01-monte-carlo-portfolio.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)  # NULL status = success (0)
  expect_true(file.exists(file.path(pkg_root, "monte-carlo-results-local.rds")))

  # Verify results structure
  results <- readRDS(file.path(pkg_root, "monte-carlo-results-local.rds"))
  expect_type(results$results, "list")
  expect_true(results$elapsed > 0)
  expect_equal(results$mode, "local")

  # Cleanup
  unlink(file.path(pkg_root, "monte-carlo-results-local.rds"))
})

test_that("Monte Carlo example runs with staRburst", {
  skip_if_no_integration()
  skip_if_not(
    Sys.getenv("USE_STARBURST") == "TRUE",
    "AWS tests disabled. Set USE_STARBURST=TRUE to enable."
  )

  pkg_root <- get_pkg_root()

  # Run example with staRburst
  result <- withr::with_envvar(
    c(
      USE_STARBURST = "TRUE",
      STARBURST_WORKERS = "10",  # Small worker count for testing
      AWS_PROFILE = Sys.getenv("AWS_PROFILE", "aws")
    ),
    system2(
      "Rscript",
      args = c(file.path(pkg_root, "examples/01-monte-carlo-portfolio.R")),
      stdout = TRUE,
      stderr = TRUE
    )
  )

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "monte-carlo-results-aws.rds")))

  # Verify results structure
  results <- readRDS(file.path(pkg_root, "monte-carlo-results-aws.rds"))
  expect_type(results$results, "list")
  expect_true(results$elapsed > 0)
  expect_equal(results$mode, "aws")
  expect_equal(results$workers, 10)

  # Cleanup
  unlink(file.path(pkg_root, "monte-carlo-results-aws.rds"))
})

test_that("Bootstrap example runs locally", {
  skip_if_no_integration()

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(USE_STARBURST = "FALSE"),
      system2(
        "Rscript",
        args = c("examples/02-bootstrap-confidence-intervals.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "bootstrap-results-local.rds")))

  results <- readRDS(file.path(pkg_root, "bootstrap-results-local.rds"))
  expect_type(results$boot_results, "list")
  expect_length(results$ci, 2)
  expect_true(results$ci[1] < results$ci[2])

  unlink(file.path(pkg_root, "bootstrap-results-local.rds"))
})

test_that("Bootstrap example runs with staRburst", {
  skip_if_no_integration()
  skip_if_not(Sys.getenv("USE_STARBURST") == "TRUE")

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(
        USE_STARBURST = "TRUE",
        STARBURST_WORKERS = "10",
        AWS_PROFILE = Sys.getenv("AWS_PROFILE", "aws")
      ),
      system2(
        "Rscript",
        args = c("examples/02-bootstrap-confidence-intervals.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "bootstrap-results-aws.rds")))

  unlink(file.path(pkg_root, "bootstrap-results-aws.rds"))
})

test_that("Data processing example runs locally", {
  skip_if_no_integration()

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(USE_STARBURST = "FALSE"),
      system2(
        "Rscript",
        args = c("examples/03-parallel-data-processing.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "processing-results-local.rds")))

  results <- readRDS(file.path(pkg_root, "processing-results-local.rds"))
  expect_type(results$chunk_stats, "list")
  expect_true(length(results$chunk_stats) > 0)

  unlink(file.path(pkg_root, "processing-results-local.rds"))
})

test_that("Data processing example runs with staRburst", {
  skip_if_no_integration()
  skip_if_not(Sys.getenv("USE_STARBURST") == "TRUE")

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(
        USE_STARBURST = "TRUE",
        STARBURST_WORKERS = "10",
        AWS_PROFILE = Sys.getenv("AWS_PROFILE", "aws")
      ),
      system2(
        "Rscript",
        args = c("examples/03-parallel-data-processing.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "processing-results-aws.rds")))

  unlink(file.path(pkg_root, "processing-results-aws.rds"))
})

test_that("Grid search example runs locally", {
  skip_if_no_integration()

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(USE_STARBURST = "FALSE"),
      system2(
        "Rscript",
        args = c("examples/04-grid-search-tuning.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "grid-search-results-local.rds")))

  results <- readRDS(file.path(pkg_root, "grid-search-results-local.rds"))
  expect_type(results$results, "list")
  expect_type(results$best_params, "list")
  expect_true(results$best_params$cv_score > 0)

  unlink(file.path(pkg_root, "grid-search-results-local.rds"))
})

test_that("Grid search example runs with staRburst", {
  skip_if_no_integration()
  skip_if_not(Sys.getenv("USE_STARBURST") == "TRUE")

  pkg_root <- get_pkg_root()

  result <- withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(
        USE_STARBURST = "TRUE",
        STARBURST_WORKERS = "10",
        AWS_PROFILE = Sys.getenv("AWS_PROFILE", "aws")
      ),
      system2(
        "Rscript",
        args = c("examples/04-grid-search-tuning.R"),
        stdout = TRUE,
        stderr = TRUE
      )
    )
  })

  expect_equal(attr(result, "status"), NULL)
  expect_true(file.exists(file.path(pkg_root, "grid-search-results-aws.rds")))

  unlink(file.path(pkg_root, "grid-search-results-aws.rds"))
})

test_that("All examples produce consistent results", {
  skip_if_no_integration()
  skip_if_not(Sys.getenv("USE_STARBURST") == "TRUE")

  pkg_root <- get_pkg_root()

  # This test verifies that AWS and local execution produce similar results
  # (within statistical tolerance for random processes)

  # Run Monte Carlo both ways with same seed
  withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(USE_STARBURST = "FALSE"),
      system2(
        "Rscript",
        args = c("examples/01-monte-carlo-portfolio.R"),
        stdout = FALSE,
        stderr = FALSE
      )
    )
  })

  withr::with_dir(pkg_root, {
    withr::with_envvar(
      c(
        USE_STARBURST = "TRUE",
        STARBURST_WORKERS = "10",
        AWS_PROFILE = Sys.getenv("AWS_PROFILE", "aws")
      ),
      system2(
        "Rscript",
        args = c("examples/01-monte-carlo-portfolio.R"),
        stdout = FALSE,
        stderr = FALSE
      )
    )
  })

  # Compare results (should be statistically similar)
  local <- readRDS(file.path(pkg_root, "monte-carlo-results-local.rds"))
  aws <- readRDS(file.path(pkg_root, "monte-carlo-results-aws.rds"))

  local_means <- sapply(local$results, function(x) x$final_value)
  aws_means <- sapply(aws$results, function(x) x$final_value)

  # Results should be highly correlated (same random seeds)
  expect_true(cor(local_means, aws_means) > 0.99)

  # Cleanup
  unlink(c(
    file.path(pkg_root, "monte-carlo-results-local.rds"),
    file.path(pkg_root, "monte-carlo-results-aws.rds")
  ))
})
