---
title: Development status
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Development status}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

The following tables show the status of the implementation of each feature in the package:

```{r include=FALSE}
library(tibble)
library(knitr)
library(rprojroot)
library(stringr)
library(purrr)
library(dplyr)
library(tidyr)

proj_root <- find_root(has_file("DESCRIPTION"))
source <- list.files(proj_root, pattern = "*.R$", recursive = TRUE)

# look for trackstatus comments
status_lines <- map_df(source, function(path) {
  lines <- readLines(paste0(proj_root, "/", path))
  line_numbers <- grep("# trackstatus:", lines)

  map_df(line_numbers, function(line_number) {
    tryCatch({
      line_stripped <- gsub(" *# trackstatus: *", "", lines[[line_number]])
      line_split <- str_split_1(line_stripped, ", *")
      vals_split <- str_split(line_split, " *= *")
      names <- sapply(vals_split, function(x) x[[1]])
      values <- lapply(vals_split, function(x) x[[2]])
      df <- data.frame(setNames(values, names), check.names = FALSE)
      df$source_file <- path
      df$line_number <- line_number
      df
    }, error = function(e) {
      message("Error in ", path, " at line ", line_number, ": ", e$message)
      return(NULL)
    })
  })
})

# split feature id into prefix and slot columns
strip_prefix <- c(
  "get_" = "Getter",
  "test_get_" = "Getter test",
  "set_" = "Setter",
  "test_set_" = "Setter test"
)
status_lines_proc <- status_lines %>%
  mutate(
    prefix = str_extract(feature, "^(test_)?[gs]et_"),
    slot = str_replace(feature, "^(test_)?[gs]et_", "")
  ) %>%
  select(-feature)

# combine with missing fields
status_lines_required <- crossing(
  class = c("InMemoryAnnData", "HDF5AnnData", "Seurat", "SingleCellExperiment"),
  prefix = c("get_", "test_get_", "set_", "test_set_"),
  slot = c("X", "layers", "obs", "var", "obs_names", "var_names", "obsm", "varm", "obsp", "varp", "uns"),
  status = "missing"
)
status <- bind_rows(
  status_lines_proc,
  status_lines_required %>% anti_join(status_lines_proc, by = c("class", "prefix", "slot"))
)

# check duplicated status
status_dup <- status %>%
  group_by(class, prefix, slot) %>%
  filter(n() > 1) %>%
  ungroup() %>%
  mutate(str = paste0(source_file, "#", line_number, " -- ", class, " ", prefix, slot))
if (nrow(status_dup) > 0) {
  stop("Duplicated status lines found:\n", paste(status_dup$str, collapse = "\n"))
}

# create formatted data frame for printing
status_formatted <-
  status %>%
  mutate(
    prefix_formatted = strip_prefix[prefix],
    status_formatted = ifelse(
      status == "missing",
      "",
      paste0(
        "[", c("done" = "✓", "wip" = "~", "missing" = "")[status],
        "](https://github.com/scverse/anndataR/blob/main/", source_file,
        "#L", line_number, ")"
      )
    )
  ) %>%
  select(class, Slot = slot, prefix_formatted, status_formatted) %>%
  spread(prefix_formatted, status_formatted)
```

```{r echo=FALSE, results="asis"}
# loop over each of the classes and print the table as a markdown
for (class in unique(status_formatted$class)) {
  cat("### ", class, "\n\n\n", sep = "")

  df <- status_formatted %>%
    filter(class == !!class) %>%
    select(-class) %>%
    knitr::kable(escape = FALSE)
  cat(paste(as.character(df), collapse = "\n"))
  cat("\n\n")
}
```
