#' @importFrom stats p.adjust
#' @importFrom S4Vectors DataFrame
#' @importFrom metapod groupedHolmMin
#' @import augere.core
.generateHolmMinCommands <- function(df.name, genes.name, min.n, min.prop, has.LogFC) {
    template <- 'local({
    df <- <%= DF_NAME %>
    genes <- factor(<%= GENES_NAME %>)
    keep <- !is.na(df$PValue)
    df <- df[keep,,drop=FALSE]
    genes <- genes[keep]

    num.barcodes <- table(genes) 
    output <- S4Vectors::DataFrame(
        row.names = names(num.barcodes),
        NumBarcodes = as.integer(num.barcodes)
    )
    <%= BODY %>
    output
})'

    signed.cmds <- '
    is.up <- df$LogFC > 0
    half.p <- df$PValue / 2
    other.p <- 1 - half.p

    # Computing and combining one-sided p-values for each direction,
    # as we want genes where barcodes change in the same direction.
    p.up <- ifelse(is.up, half.p, other.p)
    holm.up <- metapod::groupedHolmMin(p.up, genes, min.n=<%= MIN_N %>, min.prop=<%= MIN_PROP %>)
    holm.up$p.value <- holm.up$p.value[rownames(output)]

    p.down <- ifelse(!is.up, half.p, other.p)
    holm.down <- metapod::groupedHolmMin(p.down, genes, min.n=<%= MIN_N %>, min.prop=<%= MIN_PROP %>)
    holm.down$p.value <- holm.down$p.value[rownames(output)]

    output$PValue <- pmin(holm.up$p.value, holm.down$p.value, 0.5) * 2
    output$FDR <- p.adjust(output$PValue, method="BH")
    output$Direction <- ifelse(holm.up$p.value < holm.down$p.value, "up", "down")
'
    signed.cmds <- replacePlaceholders(signed.cmds, list(MIN_N=min.n, MIN_PROP=min.prop))

    if (has.LogFC) {
        return(replacePlaceholders(template, list( DF_NAME=df.name, GENES_NAME=genes.name, BODY=signed.cmds)))
    }

    conditional.cmds <- '
    if ("LogFC" %in% colnames(df)) {
    <%= PAYLOAD %>
    } else {
        # If the contrast has no directionality, we just combine p-values as they are.
        holm <- metapod::groupedHolmMin(df$PValue, genes,min.n=<%= MIN_N %>, min.prop=<%= MIN_PROP %>)
        output$PValue <- holm$p.value[rownames(output)]
        output$FDR <- p.adjust(output$PValue, method="BH")
    }
'

    signed.lines <- strsplit(trimws(signed.cmds), '\n')[[1]]
    signed.lines <- sprintf("    %s", signed.lines)
    full.body <- replacePlaceholders(
        conditional.cmds,
        list(
            PAYLOAD=paste(signed.lines, collapse="\n"),
            MIN_N=min.n,
            MIN_PROP=min.prop
        )
    )
    replacePlaceholders(template, list(DF_NAME=df.name, GENES_NAME=genes.name, BODY=full.body))
}
