#' DMA
#'
#' This function carries out the driver mutation analysis.
#' @param dataMAF A MAF file rda object.
#' The MAF file must at least contain the following columns:
#' \itemize{
#' \item Hugo_Symbol eg. BRCA1
#' \item Chromosome eg. chr1
#' \item Start_Position eg. 54402
#' \item End_Position e.g. 54443
#' \item Strand eg. +
#' \item Variant_Classification
#' \item Variant_Type
#' \item Reference_Allele
#' \item Tumor_Seq_Allele1
#' \item Tumor_Seq_Allele2
#' }
#' @param dataDEGs Output DEA function.
#' @param dataPRA Output PRA function.
#' @param runCscape Bolean. If \code{FALSE} will load CScape output file from results-folder
#' Default = \code{TRUE}.
#' @param coding_file A character string. Path to and name of CScape-somatic coding file.
#' Can be downloaded at \url{http://cscape-somatic.biocompute.org.uk/#download}. The .tbi file must be placed in the same folder.
#' @param noncoding_file A charcter string. Path to and name of CScape-somatic noncoding file.
#' Can be downloaded at \url{http://cscape-somatic.biocompute.org.uk/#download}. The .tbi file must be placed in the same folder.
#' @param results_folder A character string. Path to the results generated by this function.
#'
#' @import dplyr
#' @import tidyr
#' @import tibble
#' @importFrom fuzzyjoin genome_left_join
#' @importFrom magrittr "%>%"
#' @importFrom purrr pmap
#'
#' @return List of two, containing TSGs and OCGs with at least one driver mutation. Additionally files are saved in \code{results_folder}.
#' All output files are in compressed .rda format.
#' \describe{
#' \item{DEG_mutations_annotations.rda}{All differentially expressed genes’ mutations and their annotations. These annotations include e.g. Cscape-somatic assessment, Level of Consequence, overlab with promoter sites and information from Network of Cancer Genes (NCG 7.0). All information from MAF and DEA is contained.}
#' \item{Oncogenic_mediators_annotation_summary.rda}{All oncogenic mediators and an summarisation of their mutation based on CScape-somatic assessment, Level of Consequences and total number of mutations. If a gene as previously been assessed as a driver in Network of Cancer Genes (7.0), it is annotated in a separate column. }
#' \item{Cscape_somatic_output.rda}{The file contain the cscape-somatic assessment for every mutation found in the differentially expressed genes. It is formatted exactly as the output of cscape-somatic, as if it was run in the terminal, except it is saved as .rda instead of csv. }
#' }
#'
#' @details
#' For more information about the different annotations added to the mutations please see the documentation as followes:
#' \code{data(NCG)}, \code{data(EncodePromoters)}, \code{data(LOC_protein)}
#' \code{data(LOC_transcription)} and \code{data(LOC_translation)}.
#'
#'
#' @export
#' @examples
#' \donttest{
#' DMA(dataMAF = dataMAF,
#'     dataDEGs = DEGsmatrix,
#'     dataPRA = dataPRA,
#'     coding_file = "path/css_coding.vcf.gz",
#'     noncoding_file = "path/css_noncoding.vcf.gz",
#'     results_folder = "path/results")
#'
#' #If the cscape-somatic file have already been created
#' cscape_somatic_output <- read.csv("./results/Cscape_somatic_output.csv")
#' save(cscape_somatic_output, file = "./results/Cscape_somatic_output.rda")
#'
#' DMA(dataMAF = dataMAF,
#'     dataDEGs = DEGsmatrix,
#'     dataPRA = dataPRA,
#'     runCscape = FALSE,
#'     results_folder = "./results")
#' }

DMA <- function(dataMAF,
                dataDEGs,
                dataPRA,
                runCscape = TRUE,
                coding_file,
                noncoding_file,
                results_folder = "./DMAresults") {

  # Check user input

  if (is(dim(dataMAF), "NULL")) {
    stop("The mutation data must be a non-empty table")
  }

  if (.row_names_info(dataDEGs) < 0) {
    stop("Row names were generated automatically. The input DEG table needs to
have the gene names as rownames. Double check that genes are rownames.")
  }

  if (all(names(dataPRA) %in% c("TSG", "OCG")) == FALSE) {
    stop("The two list elements in PRA data must be named TSG and OCG")
  }


  if (!is(runCscape, "logical")) {
    stop("runCscape must be either TRUE or FALSE")
  }

  if (!is(results_folder, "character")) {
    stop("The results folder must be a character vector containing the
    path to where DMA results should be stored")
  }

  # List of variable names
  variables_to_check <- c("LOC_transcription", "LOC_translation", 
                        "LOC_protein", "EncodePromoters", "NCG")

  # Check and load variables if they do not exist
  for (variable_name in variables_to_check) {
    if (! variable_name %in% names(.GlobalEnv)) {
      data(list=c(variable_name))
    }
  }

  LOC_transcription <- get("LOC_transcription")
  LOC_translation <- get("LOC_translation")
  LOC_protein <- get("LOC_protein")

  # Create Output folder
  if (dir.exists(results_folder)) {
    print("Output folder already exists")
  } else {
    dir.create(path = results_folder,
               showWarnings = TRUE,
               recursive = TRUE)
  }

  # Load data --------------------------------
  # Read maf and add ID number to each mutation
  columns <- c("Hugo_Symbol",
               "Chromosome",
               "Start_Position",
               "End_Position",
               "Strand",
               "Variant_Classification",
               "Variant_Type",
               "Reference_Allele",
               "Tumor_Seq_Allele1",
               "Tumor_Seq_Allele2")

  if (all(columns %in% names(dataMAF)) == FALSE) {
    stop("MAF file does not contain the correct columns")
  }

  dataMAF <- dataMAF %>% tibble::rowid_to_column("ID")

  drivers_moonlight <- PRAtoTibble(dataPRA)

  dataDEGs <- dataDEGs %>% tibble::rownames_to_column(var = "Hugo_Symbol")

  # Load homemade mutations effect on transcription table
  transcription_binary <- get("LOC_transcription") %>%
    pivot_longer(cols = !Variant_Classification,
                 names_to = "Variant_Type",
                 values_to = "Potential_Effect_on_Transcription")

  translation_binary <- get("LOC_translation") %>%
    pivot_longer(cols = !Variant_Classification,
                 names_to = "Variant_Type",
                 values_to = "Potential_Effect_on_Translation")

  protein_binary <- get("LOC_protein") %>%
    pivot_longer(cols = !Variant_Classification,
                 names_to = "Variant_Type",
                 values_to = "Potential_Effect_on_Protein")

  # Load ENCODE file (promoters)
  promoters <- get("EncodePromoters") %>% mutate(Annotation = "Promoter")

  # Load NCG file
  NCG <- get("NCG")

  # Wrangle data -----------------------------
  # Keep only mutations in DEGs
  DEGs_mut <- dataDEGs %>% left_join(dataMAF, by = "Hugo_Symbol")

  # CScape-somatic -------------------------
  # Lifting from one build to another
  mut_only <- DEGs_mut %>% filter(!is.na(ID))
  DEGs_mut_hg19 <- LiftMAF(Infile = mut_only, Current_Build = "GRCh38")

  if (runCscape == TRUE) {
    cscape_in <- MAFtoCscape(DEGs_mut_hg19)

    # Check coding and noncoding files exits
    if (file.exists(coding_file) == FALSE | file.exists(noncoding_file) == FALSE) {
      stop("CScape-somatic vcf files not found at provided path.")
    } else {
      # Run CScape-somatic
      print("CScape-somatic will now run. Please wait")
      cscape_somatic_output <- RunCscape_somatic(input = cscape_in,
                                                 coding_file = coding_file,
                                                 noncoding_file = noncoding_file)

      save(cscape_somatic_output, file = paste(results_folder, "cscape_somatic_output.rda", sep = "/"))
      print("CScape_somatic is finished. Output file is saved in result folder.")
    }
  } else if (runCscape == FALSE) {
    cs_flag <- file.exists(paste(results_folder, "cscape_somatic_output.rda", sep = "/"))
    if (cs_flag == TRUE) {
      print("CScape_somatic files have been found in results-folder.")
    } else {
      stop("cscape_somatic_output.rda file is not found in results-folder.
            Please provide correct path, or set runCScape = TRUE.")
    }
  }

  # Reload CScape output and add cscape_columns in case one type is not found
  cscape_cols <- c(Coding_score = NA, Noncoding_score = NA, Remark = NA)
  load(paste(results_folder, "cscape_somatic_output.rda", sep = "/"))
  cscape_somatic_output <- cscape_somatic_output %>%
    add_column(., !!!cscape_cols[setdiff(names(cscape_cols), names(.))]) %>%
    rename_with(.cols = c("Coding_score", "Noncoding_score", "Remark"),
                .fn = ~ paste("CScape_", ., sep = "")) %>%
    mutate(Variant_Type = "SNP")

  # Merge CScape results
  DEGs_mut_annotated_19 <- DEGs_mut_hg19 %>%
    separate(Chromosome,
             into = c(NA, "Chr"),
             sep = 3,
             remove = FALSE,
             convert = TRUE) %>%
    mutate(Mutant = case_when(Reference_Allele == Tumor_Seq_Allele1 ~ Tumor_Seq_Allele2,
                              Reference_Allele == Tumor_Seq_Allele2 ~ Tumor_Seq_Allele1)) %>%
    left_join(cscape_somatic_output,
              by = c("Start_Position" = "Position",
                     "Variant_Type",
                     "Chr",
                     "Mutant")) %>%
    mutate(CScape_Mut_Class = case_when((CScape_Coding_score > 0.5 | CScape_Noncoding_score > 0.5) ~ "Driver", # Driver
                                        (CScape_Coding_score <= 0.5 | CScape_Noncoding_score <= 0.5 ~ "Passenger"), # Passenger
                                        TRUE ~ "Unclassified")) %>%  # no score is found
    unique()

  # Lift back to 38
  DEGs_mut_annotated <- LiftMAF(Infile = DEGs_mut_annotated_19,
                                Current_Build = "GRCh37")

  # Annotate file --------------------------------

  # Add level of consequence ----------
  DEGs_mut_annotated <- DEGs_mut_annotated %>%
    left_join(transcription_binary,
              by = c("Variant_Classification",
                     "Variant_Type")) %>%
    left_join(translation_binary,
              by = c("Variant_Classification",
                     "Variant_Type")) %>%
    left_join(protein_binary,
              by = c("Variant_Classification",
                     "Variant_Type"))

  # Add again the DEGs with no mutations --
  # and merge driver status from moonlight
  no_muts <- DEGs_mut %>%
    filter(is.na(ID))

  DEGs_mut_annotated <- bind_rows(DEGs_mut_annotated,
                                  no_muts) %>%
    replace_na(list(CScape_Mut_Class = "No_mutations"))

  # Add drivers from moonlight ------------
  DEGs_mut_annotated <- DEGs_mut_annotated %>%
    left_join(drivers_moonlight,
              by = "Hugo_Symbol")

  ## Promoters -------------

  # Merge Encode files into one
  encode_tibble <- promoters %>%
    dplyr::select(X1, X2, X3, Annotation) %>%
    dplyr::rename("Chromosome_annot" = "X1",
                  "Annotation_Start" = "X2",
                  "Annotation_End" = "X3")

  # Join when mutation overlap with an annotations position
  mutations_encode <- genome_left_join(x = DEGs_mut_annotated,
                                       y = encode_tibble,
                                       by = c("Chromosome" = "Chromosome_annot",
                                              "Start_Position" = "Annotation_Start",
                                              "End_Position" = "Annotation_End")) %>%
    dplyr::select(-c("Chromosome_annot"))

  # If a mutation overlap with several annotation, keep them in the same row
  DEGs_mut_annotated <- mutations_encode %>%
    group_by(ID) %>%
    mutate(Annotation = toString(Annotation),
           Annotation_Start = toString(Annotation_Start),
           Annotation_End = toString(Annotation_End)) %>%
    ungroup() %>%
    unique()

  # Make summary table --------------------------

  # Summarise CScape-somatic mutation types
  Summary_per_gene_1 <- DEGs_mut_annotated %>%
    group_by(Hugo_Symbol,
             Moonlight_Oncogenic_Mediator,
             CScape_Mut_Class) %>%
    summarise(n = n()) %>%
    pivot_wider(names_from = CScape_Mut_Class,
                values_from = n,
                names_prefix = "CScape_")

  # Summarise level of consequence
  Summary_per_gene_2 <- DEGs_mut_annotated %>%
    group_by(Hugo_Symbol,
             Moonlight_Oncogenic_Mediator) %>%
    summarise(Transcription_mut_sum = sum(Potential_Effect_on_Transcription, na.rm = TRUE),
              Translation_mut_sum = sum(Potential_Effect_on_Translation, na.rm = TRUE),
              Protein_mut_sum = sum(Potential_Effect_on_Protein, na.rm = TRUE),
              Total_Mutations = sum(!is.na(ID)))

  # Join summaries and add NCG data
  Oncogenic_mediators_mutation_summary <- full_join(Summary_per_gene_1,
                                                    Summary_per_gene_2,
                                                    by = c("Hugo_Symbol",
                                                           "Moonlight_Oncogenic_Mediator")) %>%
    filter(!is.na(Moonlight_Oncogenic_Mediator)) %>%
    arrange(dplyr::desc(CScape_Driver)) %>%
    dplyr::select(!CScape_No_mutations) %>%
    left_join(NCG,
              by = c("Hugo_Symbol" = "symbol"))

  save(Oncogenic_mediators_mutation_summary,
       file = paste(results_folder, "Oncogenic_mediators_mutation_summary.rda", sep = "/"))

  # Make mutation Table  including all annotations from this analysis --------
  # NCG is joined and the table order is restructured
  DEGs_lastCol <- colnames(dataDEGs)[ncol(dataDEGs)]

  DEG_Mutations_Annotations <- DEGs_mut_annotated %>%
    left_join(NCG, by = c("Hugo_Symbol" = "symbol")) %>%
    relocate(ID) %>%
    relocate(starts_with("NCG"),
             .after = DEGs_lastCol) %>%
    relocate(any_of(c("Moonlight_gene_z_score",
                      "Moonlight_Oncogenic_Mediator",
                      "CScape_Coding_score",
                      "CScape_Noncoding_score",
                      "CScape_Mut_Class",
                      "CScape_Remark",
                      "Potential_Effect_on_Transcription",
                      "Potential_Effect_on_Translation",
                      "Potential_Effect_on_Protein",
                      "Annotation",
                      "Annotation_Start",
                      "Annotation_End")),
             .after = DEGs_lastCol) %>%
    dplyr::select(!(Chr))

  save(DEG_Mutations_Annotations,
       file = paste(results_folder, "DEG_Mutations_Annotations.rda", sep = "/"))

  # Return final list of drivers ------
  TSG <-  DEGs_mut_annotated %>%
    filter(Moonlight_Oncogenic_Mediator == "TSG",
           CScape_Mut_Class == "Driver") %>%
    dplyr::select(Hugo_Symbol) %>%
    unique() %>%
    pull()

  OCG <- DEGs_mut_annotated %>%
    filter(Moonlight_Oncogenic_Mediator == "OCG",
           CScape_Mut_Class == "Driver") %>%
    dplyr::select(Hugo_Symbol) %>%
    unique() %>%
    pull()

  return(list("TSG" = TSG, "OCG" = OCG))

}

utils::globalVariables(c("Variant_Classification", "ID", ".", "Chromosome", "X1", "X2", "X3", "Annotation",
                         "Annotation_Start", "Annotation_End", "Hugo_Symbol", "Moonlight_Oncogenic_Mediator",
                         "CScape_Mut_Class", "Potential_Effect_on_Transcription", "Potential_Effect_on_Translation",
                         "Potential_Effect_on_Protein", "CScape_Driver", "CScape_No_mutations", "Chr"))

