## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")

## ----eval = FALSE-------------------------------------------------------------
# install.packages("OPCC")

## -----------------------------------------------------------------------------
library(OPCC)

normalize_postal_code(c("m5v3a8", "K1A-0A6", "k1a0a6"))

## ----eval = FALSE-------------------------------------------------------------
# # Best dissemination area (DA) link
# pc_to_geo("M5V 3A8", level = "DA", all_links = FALSE)
# 
# # Every defensible DA link with allocation weights
# pc_to_geo("M5V 3A8", level = "DA")
# 
# # Best dissemination block (DB) link
# pc_to_geo("M5V 3A8", level = "DB", all_links = FALSE)
# 
# # Every DB link
# pc_to_geo("M5V 3A8", level = "DB")

## ----eval = FALSE-------------------------------------------------------------
# result <- pc_to_geo(c("M5V 3A8", "ZZZ 9Z9"), level = "DA")
# attr(result, "unmatched")
# #> [1] "ZZZ 9Z9"

## ----eval = FALSE-------------------------------------------------------------
# library(OPCC)
# 
# my_data <- data.frame(
#   id = 1:5,
#   postal_code = c("M5V 3A8", "K1A 0A6", "N6A 1B1", "P7A 1A1", "ZZZ 9Z9"),
#   value = c(10, 20, 30, 40, 50),
#   stringsAsFactors = FALSE
# )
# 
# # --- DA join (one best DA per postal code) ---
# 
# da <- get_da_correspondence(vintage = "2026-07-20")
# da_best <- da[da$best_link, c("postal_code", "DAUID", "allocation_weight")]
# 
# merged_da <- merge(
#   my_data,
#   da_best,
#   by = "postal_code",
#   all.x = TRUE
# )
# # Rows with unmatched postal codes keep NA for DAUID and allocation_weight.
# 
# # --- DB join (one best DB per postal code) ---
# 
# db <- get_correspondence(vintage = "2026-07-19-geonames-amendment")
# db_best <- db[db$best_link, c("postal_code", "DBUID", "DAUID", "allocation_weight")]
# 
# merged_db <- merge(
#   my_data,
#   db_best,
#   by = "postal_code",
#   all.x = TRUE
# )
# 
# # --- Keep all many-to-many links ---
# # Skip the best_link filter to retain every candidate geography and its
# # allocation weight. Your join will produce multiple rows per postal code.
# 
# merged_all <- merge(my_data, da, by = "postal_code", all.x = TRUE)

## ----eval = FALSE-------------------------------------------------------------
# library(dplyr)
# 
# da <- get_da_correspondence(vintage = "2026-07-20")
# 
# my_data |>
#   mutate(postal_code = normalize_postal_code(postal_code)) |>
#   left_join(
#     da |> filter(best_link) |> select(postal_code, DAUID, allocation_weight),
#     by = "postal_code"
#   )

## -----------------------------------------------------------------------------
list_vintages(level = "DB")
list_vintages(level = "DA")

## ----eval = FALSE-------------------------------------------------------------
# # Download using the default session cache
# db <- get_correspondence(vintage = "2026-07-19-geonames-amendment")
# da <- get_da_correspondence(vintage = "2026-07-20")
# 
# # Or use an explicit cache directory
# cache <- file.path(tempdir(), "opcc-cache")
# db <- get_correspondence(
#   vintage = "2026-07-19-geonames-amendment",
#   cache_dir = cache
# )
# 
# # Pass a pre-loaded artifact to skip re-reading
# pc_to_geo("M5V 3A8", level = "DA", correspondence = da)
# pc_to_geo("M5V 3A8", level = "DB", correspondence = db)

## ----eval = FALSE-------------------------------------------------------------
# # Download, checksum, and validate schema and invariants
# validate_release(vintage = "2026-07-19-geonames-amendment", level = "DB",
#                  cache_dir = cache)
# validate_release(vintage = "2026-07-20", level = "DA", cache_dir = cache)
# 
# # Inspect provenance metadata
# release_manifest(vintage = "2026-07-20", level = "DA", cache_dir = cache)

## ----eval = FALSE-------------------------------------------------------------
# validate_release(vintage = "2026-07-20", level = "DA",
#                  cache_dir = cache, offline = TRUE)
# da <- get_da_correspondence(vintage = "2026-07-20",
#                             cache_dir = cache, offline = TRUE)

## ----eval = FALSE-------------------------------------------------------------
# pts <- pc_to_point("K0A 0A1",
#                    point_file = "/path/to/opcc_m1_geonames_points.csv.gz")

## ----eval = FALSE-------------------------------------------------------------
# pc_to_point("K0A 0A1")
# pc_to_point("K0A 0A1", source = "geonames")

## ----eval = FALSE-------------------------------------------------------------
# my_source <- utils::read.csv("/path/to/municipal-postal-data.csv",
#                              stringsAsFactors = FALSE)

## -----------------------------------------------------------------------------
adapter <- new_source_adapter(
  source_id = "municipal_registry",
  licence = "Open Government Licence - Municipality",
  lineage = "Municipal open address registry",
  retrieval_date = "2026-07-20",
  schema_map = list(
    postal_code = "postal",
    latitude = "lat",
    longitude = "lon"
  ),
  checksum = strrep("0", 64L)
)

adapter

## ----eval = FALSE-------------------------------------------------------------
# layer <- build_source_layer(my_source, adapter, on_invalid = "quarantine")
# profile_source_layer(layer)
# 
# # `output_dir` must be an explicit path you choose; nothing is written
# # to the working directory by default.
# bundle <- contribution_bundle(layer,
#                               output_dir = file.path(tempdir(), "contributions"),
#                               fixture_rows = 100L)
# contribution_issue_url(bundle)

## ----eval = FALSE-------------------------------------------------------------
# validate_release(vintage = "2026-07-19-geonames-amendment", level = "DB")
# validate_release(vintage = "2026-07-20", level = "DA")

## ----eval = FALSE-------------------------------------------------------------
# release_manifest(vintage = "2026-07-19-geonames-amendment", level = "DB")
# release_manifest(vintage = "2026-07-20", level = "DA")

## ----eval = FALSE-------------------------------------------------------------
# db <- get_correspondence(vintage = "2026-06-26")
# da_reproduced <- aggregate_da_correspondence(db)
# 
# # Compare with the published DA artifact
# da_published <- get_da_correspondence(vintage = "2026-07-20")
# stopifnot(identical(nrow(da_reproduced), nrow(da_published)))
# stopifnot(identical(
#   sort(unique(da_reproduced$postal_code)),
#   sort(unique(da_published$postal_code))
# ))

## ----eval = FALSE-------------------------------------------------------------
# cache <- file.path(tempdir(), "opcc-cache")
# 
# validate_release(vintage = "2026-06-26", level = "DB",
#                  cache_dir = cache, offline = TRUE)
# validate_release(vintage = "2026-07-20", level = "DA",
#                  cache_dir = cache, offline = TRUE)
# 
# db <- get_correspondence(vintage = "2026-06-26",
#                          cache_dir = cache, offline = TRUE)
# da <- aggregate_da_correspondence(db)

## ----eval = FALSE-------------------------------------------------------------
# packages <- c("digest", "dplyr", "jsonlite", "readr", "sf")
# missing <- packages[!vapply(packages, requireNamespace, logical(1),
#                             quietly = TRUE)]
# if (length(missing)) install.packages(missing)

## ----eval = FALSE-------------------------------------------------------------
# build_cache <- file.path(tempdir(), "opcc-build")
# dir.create(build_cache, recursive = TRUE, showWarnings = FALSE)
# 
# nar_dir <- download_nar(cache_dir = build_cache)
# geonames_txt <- download_geonames(cache_dir = build_cache)
# bounds <- download_census_boundaries(cache_dir = build_cache)
# gaf_csv <- download_gaf(cache_dir = build_cache)

## ----eval = FALSE-------------------------------------------------------------
# centroids_csv <- build_centroids(nar_dir, geonames_txt,
#                                  output_dir = file.path(build_cache, "centroids"))

## ----eval = FALSE-------------------------------------------------------------
# rollup_csv <- build_db_assignment(
#   centroids_csv, bounds$province, bounds$db, gaf_csv,
#   output_dir = file.path(build_cache, "rollup")
# )

## ----eval = FALSE-------------------------------------------------------------
# m2_csv <- build_m2(nar_dir, bounds$db, gaf_csv, rollup_csv,
#                    output_dir = file.path(build_cache, "m2"))

## ----eval = FALSE-------------------------------------------------------------
# db <- utils::read.csv(m2_csv, stringsAsFactors = FALSE)
# da <- aggregate_da_correspondence(db)

## ----eval = FALSE-------------------------------------------------------------
# stopifnot(!anyDuplicated(db[c("postal_code", "DBUID")]))
# weights <- tapply(db$allocation_weight, db$postal_code, sum)
# stopifnot(all(abs(weights - 1) < 1e-8))
# stopifnot(all(tapply(db$best_link, db$postal_code, sum) == 1L))

