#' Create Orbitrap Fusion Lumos method.xml files.
#'
#' This function is used to create Orbitrap Fusion Lumos method files from
#' a tree-like `list` experiment generated by e.g.
#' [createExperimentsFragmentOptimisation()].
#'
#' @param exps `list`, generated by e.g.
#' [createExperimentsFragmentOptimisation()]
#' @param pattern `character`, file name pattern for the method.xml files.
#' @param verbose `logical`, verbose output?
#'
#' @details
#'
#' * `exps`: a named tree-like `list` object generated by e.g.
#' [createExperimentsFragmentOptimisation()]. Its names are used as filename.
#' * `pattern`: The file name pattern used to name different method files.
#'  It must contain a `"%s"` that is replaced by the conditions defined in
#'  `groupBy`.
#'
#' **DEFUNCT** options:
#'
#' * `ms1Settings`:
#'   A `list` of MS1 settings. This has to be a named `list`.
#'   Valid MS1 settings are:
#'   `c("FirstMass", "LastMass", "Microscans", "MaxITTimeInMS", "AgcTarget")`
#' * `ms2Settings`:
#'   A `list` of MS2 settings. This has to be a named `list`.
#'   Valid MS2 settings are:
#'   `c("ActivationType", "IsolationWindow", "EnableMultiplexIons",
#'      "EnableMSXIds", "MaxNoOfMultiplexIons", "OrbitrapResolution",
#'      "AgcTarget", "MinAgcTarget", "MaxITTimeInMS", "Microscans",
#'      "ETDReactionTime", "ETDReagentTarget",
#'      "MaximumETDReagentInjectionTime", "UseInternalCalibratedETD",
#'      "ETDSupplementalActivationEnergy", "ETDSupplementalActivation")`
#' * `groupBy`: The `groupBy` parameter is used to split methods into
#'  different files. Valid entries are all settings that could be used in
#'  `ms2Settings` and `"replication"`.
#' * `massLabeling`: The Orbitrap Fusion devices seems not to respect the
#'  start and end times of the runs given in the method.xml files. That's why it
#'  is nearly impossible to identify the run with its conditions based on the
#'  timings. If `massLabeling` is `TRUE` (default) the mass values given
#'  in `mz` are rounded to the first decimal place and the second to fourth
#'  decimal place is used as numeric identifier.
#'
#' @seealso [createExperimentsFragmentOptimisation()]
#' @author Sebastian Gibb \email{mail@@sebastiangibb.de}, Pavel V. Shliaha
#' \email{pavels@@bmb.sdu.dk}
#' @examples
#' ms1 <- expandMs1Conditions(FirstMass=400, LastMass=1200, Microscans=as.integer(10))
#'
#' targetMz <- cbind(mz=c(560.6, 700.5, 933.7), z=rep(1, 3))
#' common <- list(
#'     OrbitrapResolution="R120K",
#'     IsolationWindow=1,
#'     MaxITTimeInMS=200,
#'     Microscans=as.integer(40),
#'     AgcTarget=c(1e5, 5e5, 1e6)
#' )
#' cid <- expandTms2Conditions(
#'     MassList=targetMz,
#'     common,
#'     ActivationType="CID",
#'     CIDCollisionEnergy=seq(7, 35, 7)
#' )
#' hcd <- expandTms2Conditions(
#'     MassList=targetMz,
#'     common,
#'     ActivationType="HCD",
#'     HCDCollisionEnergy=seq(7, 35, 7)
#' )
#' etd <- expandTms2Conditions(
#'     MassList=targetMz,
#'     common,
#'     ActivationType="ETD",
#'     ETDReagentTarget=c(1e6, 5e6, 1e7),
#'     ETDReactionTime=c(2.5, 5, 10, 15, 30, 50),
#'     ETDSupplementalActivation=c("None", "ETciD", "EThcD"),
#'     ETDSupplementalActivationEnergy=seq(7, 35, 7)
#' )
#' exps <- createExperimentsFragmentOptimisation(ms1=ms1, cid, hcd, etd,
#'     groupBy=c("AgcTarget", "replication"), nMs2perMs1=10, scanDuration=0.5,
#'     replications=2, randomise=TRUE
#' )
#' writeMethodXmls(exps=exps)
#' @export
writeMethodXmls <- function(exps, pattern="method-%s.xml",
                            verbose=interactive()) {

    requireNamespace("xml2")

    if (!grepl("%s", pattern)) {
        stop(
            sQuote("pattern"),
            " has to contain '%s' to be replaced by the ",
            "grouping condition."
        )
    }

    fn <- .validFilename(sprintf(pattern, names(exps)))
    for (i in seq(along=exps)) {
        if (verbose) {
            message("Writing ", fn[i])
        }
        xml2::write_xml(xml2::as_xml_document(exps[[i]]), file=fn[i])
    }
}
