code: /* eslint-disable
      camelcase,
      handle-callback-err,
      no-return-assign,
      no-unused-vars,
  */
  // TODO: This file was created by bulk-decaffeinate.
  // Fix any style issues and re-enable lint.
  /*
   * decaffeinate suggestions:
   * DS102: Remove unnecessary code created because of implicit returns
   * DS103: Rewrite code to no longer use __guard__
   * DS207: Consider shorter variations of null checks
   * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
   */
  let LatexRunner
  const Path = require('path')
  const Settings = require('settings-sharelatex')
  const logger = require('logger-sharelatex')
  const Metrics = require('./Metrics')
  const CommandRunner = require('./CommandRunner')
  const fs = require('fs')
  
  const ProcessTable = {} // table of currently running jobs (pids or docker container names)
  
  module.exports = LatexRunner = {
    runLatex(project_id, options, callback) {
      let command
      if (callback == null) {
        callback = function (error) {}
      }
      let {
        directory,
        mainFile,
        compiler,
        timeout,
        image,
        environment,
        flags,
        compileGroup
      } = options
      if (!compiler) {
        compiler = 'pdflatex'
      }
      if (!timeout) {
        timeout = 60000
      } // milliseconds
  
      logger.log(
        {
          directory,
          compiler,
          timeout,
          mainFile,
          environment,
          flags,
          compileGroup
        },
        'starting compile'
      )
  
      // We want to run latexmk on the tex file which we will automatically
      // generate from the Rtex/Rmd/md file.
      mainFile = mainFile.replace(/\.(Rtex|md|Rmd)$/, '.tex')
  
      if (compiler === 'pdflatex') {
        command = LatexRunner._pdflatexCommand(mainFile, flags)
      } else if (compiler === 'latex') {
        command = LatexRunner._latexCommand(mainFile, flags)
      } else if (compiler === 'xelatex') {
        command = LatexRunner._xelatexCommand(mainFile, flags)
      } else if (compiler === 'lualatex') {
        command = LatexRunner._lualatexCommand(mainFile, flags)
      } else {
        return callback(new Error(`unknown compiler: ${compiler}`))
      }
  
      if (Settings.clsi != null ? Settings.clsi.strace : undefined) {
        command = ['strace', '-o', 'strace', '-ff'].concat(command)
      }
  
      const id = `${project_id}` // record running project under this id
  
      return (ProcessTable[id] = CommandRunner.run(
        project_id,
        command,
        directory,
        image,
        timeout,
        environment,
        compileGroup,
        function (error, output) {
          delete ProcessTable[id]
          if (error != null) {
            return callback(error)
          }
          const runs =
            __guard__(
              __guard__(output != null ? output.stderr : undefined, (x1) =>
                x1.match(/^Run number \d+ of .*latex/gm)
              ),
              (x) => x.length
            ) || 0
          const failed =
            __guard__(output != null ? output.stdout : undefined, (x2) =>
              x2.match(/^Latexmk: Errors/m)
            ) != null
              ? 1
              : 0
          // counters from latexmk output
          const stats = {}
          stats['latexmk-errors'] = failed
          stats['latex-runs'] = runs
          stats['latex-runs-with-errors'] = failed ? runs : 0
          stats[`latex-runs-${runs}`] = 1
          stats[`latex-runs-with-errors-${runs}`] = failed ? 1 : 0
          // timing information from /usr/bin/time
          const timings = {}
          const stderr = output != null ? output.stderr : undefined
          timings['cpu-percent'] =
            __guard__(
              stderr != null
                ? stderr.match(/Percent of CPU this job got: (\d+)/m)
                : undefined,
              (x3) => x3[1]
            ) || 0
          timings['cpu-time'] =
            __guard__(
              stderr != null
                ? stderr.match(/User time.*: (\d+.\d+)/m)
                : undefined,
              (x4) => x4[1]
            ) || 0
          timings['sys-time'] =
            __guard__(
              stderr != null
                ? stderr.match(/System time.*: (\d+.\d+)/m)
                : undefined,
              (x5) => x5[1]
            ) || 0
          // record output files
          LatexRunner.writeLogOutput(project_id, directory, output, () => {
            return callback(error, output, stats, timings)
          })
        }
      ))
    },
  
    writeLogOutput(project_id, directory, output, callback) {
      if (!output) {
        return callback()
      }
      // internal method for writing non-empty log files
      function _writeFile(file, content, cb) {
        if (content && content.length > 0) {
          fs.writeFile(file, content, (err) => {
            if (err) {
              logger.error({ project_id, file }, 'error writing log file') // don't fail on error
            }
            cb()
          })
        } else {
          cb()
        }
      }
      // write stdout and stderr, ignoring errors
      _writeFile(Path.join(directory, 'output.stdout'), output.stdout, () => {
        _writeFile(Path.join(directory, 'output.stderr'), output.stderr, () => {
          callback()
        })
      })
    },
  
    killLatex(project_id, callback) {
      if (callback == null) {
        callback = function (error) {}
      }
      const id = `${project_id}`
      logger.log({ id }, 'killing running compile')
      if (ProcessTable[id] == null) {
        logger.warn({ id }, 'no such project to kill')
        return callback(null)
      } else {
        return CommandRunner.kill(ProcessTable[id], callback)
      }
    },
  
    _latexmkBaseCommand(flags) {
      let args = [
        'latexmk',
        '-cd',
        '-f',
        '-jobname=output',
        '-auxdir=$COMPILE_DIR',
        '-outdir=$COMPILE_DIR',
        '-synctex=1',
        '-interaction=batchmode'
      ]
      if (flags) {
        args = args.concat(flags)
      }
      return (
        __guard__(
          Settings != null ? Settings.clsi : undefined,
          (x) => x.latexmkCommandPrefix
        ) || []
      ).concat(args)
    },
  
    _pdflatexCommand(mainFile, flags) {
      return LatexRunner._latexmkBaseCommand(flags).concat([
        '-pdf',
        Path.join('$COMPILE_DIR', mainFile)
      ])
    },
  
    _latexCommand(mainFile, flags) {
      return LatexRunner._latexmkBaseCommand(flags).concat([
        '-pdfdvi',
        Path.join('$COMPILE_DIR', mainFile)
      ])
    },
  
    _xelatexCommand(mainFile, flags) {
      return LatexRunner._latexmkBaseCommand(flags).concat([
        '-xelatex',
        Path.join('$COMPILE_DIR', mainFile)
      ])
    },
  
    _lualatexCommand(mainFile, flags) {
      return LatexRunner._latexmkBaseCommand(flags).concat([
        '-lualatex',
        Path.join('$COMPILE_DIR', mainFile)
      ])
    }
  }
  
  function __guard__(value, transform) {
    return typeof value !== 'undefined' && value !== null
      ? transform(value)
      : undefined
  }
  