#' Generate Documentation for an R Package
#'
#' Main function for tinyrox. Parses R source files for documentation
#' comments and generates Rd files and NAMESPACE.
#'
#' @param path Path to package root directory. Default is current directory.
#' @param namespace How to handle NAMESPACE generation. One of
#' \describe{
#'   \item{"overwrite"}{Fully regenerate NAMESPACE (default)}
#'   \item{"append"}{Insert between ## tinyrox start/end markers}
#'   \item{"none"}{Don't modify NAMESPACE}
#' }
#' @param cran_check Run CRAN compliance checks (code issues and missing
#'   examples) and undocumented-parameter warnings. Default TRUE.
#' @param silent Operate less verbose without messages. Default FALSE.
#' @param prune_rd Remove stale Rd files for topics no longer documented
#'   (e.g. after a rename or deletion)? Only files tinyrox generated are
#'   removed; hand-written Rd is never touched. Default TRUE. Set FALSE to
#'   leave existing Rd in place.
#' @return Invisibly returns a list with:
#'   - rd_files: character vector of generated Rd file paths
#'   - pruned: character vector of stale Rd file paths removed
#'   - namespace: path to NAMESPACE file (or NULL if mode="none")
#'
#' @export
#'
#' @examples
#' \donttest{
#' # Create a minimal package in tempdir
#' pkg <- file.path(tempdir(), "mypkg")
#' dir.create(file.path(pkg, "R"), recursive = TRUE, showWarnings = FALSE)
#' writeLines("Package: mypkg\nTitle: Test\nVersion: 0.1.0",
#'     file.path(pkg, "DESCRIPTION"))
#' writeLines(c(
#'     "#' Add two numbers",
#'     "#' @param x A number",
#'     "#' @param y A number",
#'     "#' @export",
#'     "add <- function(x, y) x + y"),
#'     file.path(pkg, "R", "add.R"))
#'
#' # Document the package
#' document(pkg, cran_check = FALSE)
#'
#' # Clean up
#' unlink(pkg, recursive = TRUE)
#' }
document <- function(path = ".",
                     namespace = c("overwrite", "append", "none"),
                     cran_check = TRUE, silent = FALSE, prune_rd = TRUE) {
    namespace <- match.arg(namespace)

    # Validate path
    if (!file.exists(file.path(path, "DESCRIPTION"))) {
        stop("No DESCRIPTION file found in ", path,
             ". Is this an R package?", call. = FALSE)
    }

    # Check CRAN compliance
    if (cran_check) {
        check_cran(path)
    }

    # Parse all R files
    if (!silent) {
        message("Parsing R files...")
    }
    blocks <- parse_package(path)

    if (length(blocks) == 0) {
        if (!silent) {
            message("No documentation blocks found.")
        }
        # Nothing is generated this run, so every tinyrox-owned Rd is now stale
        # (e.g. the last documented topic was deleted). Prune them too.
        pruned <- character()
        if (prune_rd) {
            pruned <- prune_stale_rd(path, character(), silent)
        }
        return(invisible(list(rd_files = character(), pruned = pruned,
                              namespace = NULL)))
    }

    if (!silent) {
        message("Found ", length(blocks), " documentation block(s).")
    }

    # Generate Rd files
    if (!silent) {
        message("Generating Rd files...")
    }
    rd_files <- generate_all_rd(blocks, path, cran_check)
    if (!silent) {
        message("Generated ", length(rd_files), " Rd file(s).")
    }

    # Prune stale Rd left behind by renamed or deleted topics (tinyrox-owned
    # files only; hand-written Rd is never removed).
    pruned <- character()
    if (prune_rd) {
        pruned <- prune_stale_rd(path, rd_files, silent)
    }

    # Generate NAMESPACE
    ns_file <- NULL
    if (namespace != "none") {
        if (!silent) {
            message("Generating NAMESPACE...")
        }
        ns_content <- generate_namespace(blocks)
        ns_file <- write_namespace(ns_content, path, namespace)
        if (!silent) {
            message("Updated NAMESPACE.")
        }
    }

    if (!silent) {
        message("Leaving DESCRIPTION alone as one should.")
    }

    invisible(list(rd_files = rd_files, pruned = pruned, namespace = ns_file))
}

#' Clean Generated Files
#'
#' Removes all Rd files from man/ directory.
#'
#' @param path Path to package root directory.
#' @param namespace Also remove NAMESPACE? Default FALSE.
#'
#' @return No return value, called for side effects.
#'
#' @export
#'
#' @examples
#' \donttest{
#' # Create a minimal package in tempdir
#' pkg <- file.path(tempdir(), "mypkg")
#' dir.create(file.path(pkg, "man"), recursive = TRUE, showWarnings = FALSE)
#' writeLines("Package: mypkg\nTitle: Test\nVersion: 0.1.0",
#'     file.path(pkg, "DESCRIPTION"))
#' writeLines("placeholder", file.path(pkg, "man", "test.Rd"))
#'
#' clean(pkg)
#'
#' # Clean up
#' unlink(pkg, recursive = TRUE)
#' }
clean <- function(path = ".", namespace = FALSE) {
    man_dir <- file.path(path, "man")

    if (dir.exists(man_dir)) {
        rd_files <- list.files(man_dir, pattern = "\\.Rd$", full.names = TRUE)
        if (length(rd_files) > 0) {
            file.remove(rd_files)
            message("Removed ", length(rd_files), " Rd file(s).")
        }
    }

    if (namespace) {
        ns_file <- file.path(path, "NAMESPACE")
        if (file.exists(ns_file)) {
            file.remove(ns_file)
            message("Removed NAMESPACE.")
        }
    }

    invisible(NULL)
}
