#' @title Dictionary of Tasks
#'
#' @usage NULL
#' @format [R6::R6Class] object inheriting from [mlr3misc::Dictionary].
#' @description
#' A simple [mlr3misc::Dictionary] storing objects of class [Task].
#' Each task has an associated help page, see `mlr_tasks_[id]`.
#'
#' This dictionary can get populated with additional tasks by add-on packages,
#' e.g. \CRANpkg{mlr3data}, \CRANpkg{mlr3proba} or \CRANpkg{mlr3cluster}.
#' \CRANpkg{mlr3oml} allows to interact with [OpenML](https://www.openml.org).
#'
#' For a more convenient way to retrieve and construct tasks, see [tsk()]/[tsks()].
#'
#' @section Methods:
#' See [mlr3misc::Dictionary].
#'
#' @section S3 methods:
#' * `as.data.table(dict, ..., objects = FALSE)`\cr
#'   [mlr3misc::Dictionary] -> [data.table::data.table()]\cr
#'   Returns a [data.table::data.table()] with columns "key", "label", "task_type", "nrow", "ncol", "properties",
#'   and the number of features of type "lgl", "int", "dbl", "chr", "fct" and "ord", respectively.
#'   If `objects` is set to `TRUE`, the constructed objects are returned in the list column named `object`.
#'
#' @family Dictionary
#' @family Task
#' @seealso
#' Sugar functions: [tsk()], [tsks()]
#'
#' Extension Packages: \CRANpkg{mlr3data}
#' @export
#' @examples
#' as.data.table(mlr_tasks)
#' task = mlr_tasks$get("penguins") # same as tsk("penguins")
#' head(task$data())
#'
#' # Add a new task, based on a subset of penguins:
#' data = palmerpenguins::penguins
#' data$species = factor(ifelse(data$species == "Adelie", "1", "0"))
#' task = TaskClassif$new("penguins.binary", data, target = "species", positive = "1")
#'
#' # add to dictionary
#' mlr_tasks$add("penguins.binary", task)
#'
#' # list available tasks
#' mlr_tasks$keys()
#'
#' # retrieve from dictionary
#' mlr_tasks$get("penguins.binary")
#'
#' # remove task again
#' mlr_tasks$remove("penguins.binary")
mlr_tasks = R6Class("DictionaryTask",
  inherit = Dictionary,
  cloneable = FALSE
)$new()


#' @export
as.data.table.DictionaryTask = function(x, ..., objects = FALSE) {
  assert_flag(objects)

  setkeyv(map_dtr(x$keys(), function(key) {
    t = tryCatch(x$get(key),
      missingDefaultError = function(e) NULL)
    if (is.null(t)) {
      return(list(key = key))
    }

    feats = translate_types(t$feature_types$type)
    insert_named(
      c(list(key = key, label = t$label, task_type = t$task_type, nrow = t$nrow, ncol = t$ncol, properties = list(t$properties)), table(feats)),
      if (objects) list(object = list(t))
    )
  }, .fill = TRUE), "key")[]
}
