options(stringsAsFactors = FALSE, scipen = 999)

script_path <- function() {
  args <- commandArgs(trailingOnly = FALSE)
  hit <- grep("^--file=", args, value = TRUE)
  if (length(hit)) normalizePath(sub("^--file=", "", hit[[1]]), mustWork = FALSE) else NA_character_
}

this_file <- script_path()
project_root <- if (!is.na(this_file)) {
  normalizePath(file.path(dirname(this_file), ".."), mustWork = FALSE)
} else {
  normalizePath(getwd(), mustWork = FALSE)
}

paths <- list(
  raw = file.path(project_root, "data", "raw"),
  derived = file.path(project_root, "data", "derived"),
  tables = file.path(project_root, "outputs", "tables"),
  figures = file.path(project_root, "outputs", "figures"),
  diagnostics = file.path(project_root, "outputs", "diagnostics"),
  manuscript = file.path(project_root, "manuscript"),
  submission = file.path(project_root, "submission")
)
invisible(lapply(paths, dir.create, recursive = TRUE, showWarnings = FALSE))

config <- list(
  primary_benchmark = 475,
  low_benchmark = 400,
  pv_count = 5L,
  seed = 20260812L,
  g45_systems = c("Georgia", "Italy", "Jordan", "Korea, Rep. of", "Kosovo", "Montenegro",
                  "North Macedonia", "Slovenia", "Sweden"),
  g89_systems = c("Jordan", "Korea, Rep. of", "Sweden"),
  primary_grade_band = "G4-5",
  reference_weighting = "equal_system",
  common_support_quantiles = c(0.01, 0.99),
  mnar_deltas = c(0, -10, -20, -40),
  threshold_grid = c(390, 400, 410, 465, 475, 485),
  primary_hysteresis = c(baseline = 450, followup = 500),
  low_hysteresis = c(baseline = 380, followup = 420),
  standardization_eta_limit = 30,
  response_eta_limit = 30,
  response_propensity_floor = 0.05,
  strict_cell_grid = 4L,
  strict_cell_min_n = 5L,
  strict_cell_min_ess = 3
)

standardization_specifications <- list(
  primary = list(
    systems = "all", surface = "quadratic_interaction",
    target = "equal_system", support = "rectangle_01_99"
  ),
  population_target = list(
    systems = "all", surface = "quadratic_interaction",
    target = "pooled_population", support = "rectangle_01_99"
  ),
  leave_korea_out = list(
    systems = "without_korea", surface = "quadratic_interaction",
    target = "equal_system", support = "rectangle_01_99"
  ),
  strict_common_cells = list(
    systems = "all", surface = "quadratic_interaction",
    target = "equal_system", support = "strict_common_cells"
  ),
  additive_linear = list(
    systems = "all", surface = "additive_linear",
    target = "equal_system", support = "rectangle_01_99"
  ),
  linear_interaction = list(
    systems = "all", surface = "linear_interaction",
    target = "equal_system", support = "rectangle_01_99"
  )
)

urls <- c(
  data_r_g45 = "https://timss2023.org/wp-content/uploads/data/T23L_Data_R_G4-5.zip",
  data_r_g89 = "https://timss2023.org/wp-content/uploads/data/T23L_Data_R_G8-9.zip",
  codebook_g45 = "https://timss2023.org/wp-content/uploads/data/T23L_Codebook_G4-5.xlsx",
  codebook_g89 = "https://timss2023.org/wp-content/uploads/data/T23L_Codebook_G8-9.xlsx",
  user_guide = "https://timss2023.org/wp-content/uploads/data/T23L_UG-International-Database.pdf",
  r_programs = "https://timss2023.org/wp-content/uploads/data/T23L_Programs_R.zip",
  technical_report = "https://timss2023.org/wp-content/uploads/methods/T23L_TechnicalReport.pdf",
  chapter13 = "https://timss2023.org/wp-content/uploads/2024/12/T23_TR_Chap13.pdf",
  report_math_g45 = "https://timss2023.org/wp-content/uploads/longitudinal/1-1-1a-b-ach-g5m.xlsx",
  report_math_benchmark_g45 = "https://timss2023.org/wp-content/uploads/longitudinal/1-1-3-ach-bmk-dist-g5m.xlsx",
  report_science_g45 = "https://timss2023.org/wp-content/uploads/longitudinal/2-1-1a-b-ach-g5s.xlsx",
  report_science_benchmark_g45 = "https://timss2023.org/wp-content/uploads/longitudinal/2-1-3-ach-bmk-dist-g5s.xlsx",
  report_math_g89 = "https://timss2023.org/wp-content/uploads/longitudinal/1-2-1a-b-ach-g9m.xlsx",
  report_science_g89 = "https://timss2023.org/wp-content/uploads/longitudinal/2-2-1a-b-ach-g9s.xlsx",
  report_sample_a1 = "https://timss2023.org/wp-content/uploads/2025/10/A-1_students-assessed.xlsx",
  report_participation_a5 = "https://timss2023.org/wp-content/uploads/2025/10/A-5_samp-participation.xlsx"
)

raw_files <- c(
  data_r_g45 = "T23L_Data_R_G4-5.zip",
  data_r_g89 = "T23L_Data_R_G8-9.zip",
  codebook_g45 = "T23L_Codebook_G4-5.xlsx",
  codebook_g89 = "T23L_Codebook_G8-9.xlsx",
  user_guide = "T23L_UG-International-Database.pdf",
  r_programs = "T23L_Programs_R.zip",
  technical_report = "T23L_TechnicalReport.pdf",
  chapter13 = "T23_TR_Chap13.pdf",
  report_math_g45 = "report_1-1-1a-b-ach-g5m.xlsx",
  report_math_benchmark_g45 = "report_1-1-3-ach-bmk-g5m.xlsx",
  report_science_g45 = "report_2-1-1a-b-ach-g5s.xlsx",
  report_science_benchmark_g45 = "report_2-1-3-ach-bmk-g5s.xlsx",
  report_math_g89 = "report_1-2-1a-b-ach-g9m.xlsx",
  report_science_g89 = "report_2-2-1a-b-ach-g9s.xlsx",
  report_sample_a1 = "report_A-1_students-assessed.xlsx",
  report_participation_a5 = "report_A-5_samp-participation.xlsx"
)

# Frozen fingerprints of the official files used for this analysis. A changed
# upstream file must be reviewed explicitly rather than silently replacing a
# cached source and changing the analysis lineage.
expected_source_md5 <- c(
  data_r_g45 = "9e4d40778cb1f4c171ef36135f0cb224",
  data_r_g89 = "9ceb53906261f29dc4d81578242f4898",
  codebook_g45 = "d7c05fd9f981b60dae29487c98e1b248",
  codebook_g89 = "55a4c3f8e95e07fc638cb14f6f51ca2f",
  user_guide = "01fbcd101699a1a1e696d90ba1382b68",
  r_programs = "3c0197ca3ed1af16da06a841b1c27f99",
  technical_report = "df1011badaa926cb648f2b9a49cee6a6",
  chapter13 = "e41babf7bed74cb390ba0d4810b97e9e",
  report_math_g45 = "deb71f03004de89dfa3e9bfa8fc47de8",
  report_math_benchmark_g45 = "3613a2de0797d0fb1ca8ecb9cdfef510",
  report_science_g45 = "602f46d50bc3af36c82ec6c1198dc507",
  report_science_benchmark_g45 = "116a573a89fabb97e6fe1f1acb42af21",
  report_math_g89 = "2d7f59a13e9cf81d50fc5a072c7120d3",
  report_science_g89 = "dd03db9da12e8125e6e269f1d7670bdc",
  report_sample_a1 = "a1900f0c308233017b50500b7e9a0308",
  report_participation_a5 = "9e90eb3aa76dd00d15f1c8427cb075ac"
)

stopifnot(
  identical(names(urls), names(raw_files)),
  identical(names(urls), names(expected_source_md5))
)

set.seed(config$seed)
