Path = require "path"
Settings = require "settings-sharelatex"
logger = require "logger-sharelatex"
Metrics = require "./Metrics"
CommandRunner = require "./CommandRunner"

ProcessTable = {}  # table of currently running jobs (pids or docker container names)

module.exports = LatexRunner =
	runLatex: (project_id, options, callback = (error) ->) ->
		{directory, mainFile, compiler, timeout, image, environment} = options
		compiler ||= "pdflatex"
		timeout  ||= 60000 # milliseconds

		logger.log directory: directory, compiler: compiler, timeout: timeout, mainFile: mainFile, environment: environment, "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
		else if compiler == "latex"
			command = LatexRunner._latexCommand mainFile
		else if compiler == "xelatex"
			command = LatexRunner._xelatexCommand mainFile
		else if compiler == "lualatex"
			command = LatexRunner._lualatexCommand mainFile
		else
			return callback new Error("unknown compiler: #{compiler}")
		
		if Settings.clsi?.strace
			command = ["strace", "-o", "strace", "-ff"].concat(command)

		id = "#{project_id}" # record running project under this id

		ProcessTable[id] = CommandRunner.run project_id, command, directory, image, timeout, environment, (error, output) ->
			delete ProcessTable[id]
			return callback(error) if error?
			runs = output?.stderr?.match(/^Run number \d+ of .*latex/mg)?.length or 0
			failed = if output?.stdout?.match(/^Latexmk: Errors/m)? then 1 else 0
			# counters from latexmk output
			stats = {}
			stats["latexmk-errors"] = failed
			stats["latex-runs"] = runs
			stats["latex-runs-with-errors"] = if failed then runs else 0
			stats["latex-runs-#{runs}"] = 1
			stats["latex-runs-with-errors-#{runs}"] = if failed then 1 else 0
			# timing information from /usr/bin/time
			timings = {}
			stderr = output?.stderr
			timings["cpu-percent"] = stderr?.match(/Percent of CPU this job got: (\d+)/m)?[1] or 0
			timings["cpu-time"] = stderr?.match(/User time.*: (\d+.\d+)/m)?[1] or 0
			timings["sys-time"] = stderr?.match(/System time.*: (\d+.\d+)/m)?[1] or 0
			callback error, output, stats, timings

	killLatex: (project_id, callback = (error) ->) ->
		id = "#{project_id}"
		logger.log {id:id}, "killing running compile"
		if not ProcessTable[id]?
			logger.warn {id}, "no such project to kill"
			return callback(null)
		else
			CommandRunner.kill ProcessTable[id], callback

	_latexmkBaseCommand: (Settings?.clsi?.latexmkCommandPrefix || []).concat([
		"latexmk", "-cd", "-f", "-jobname=output", "-auxdir=$COMPILE_DIR", "-outdir=$COMPILE_DIR",
		"-synctex=1","-interaction=batchmode"
		])

	_pdflatexCommand: (mainFile) ->
		LatexRunner._latexmkBaseCommand.concat [
			"-pdf",
			Path.join("$COMPILE_DIR", mainFile)
		]
		
	_latexCommand: (mainFile) ->
		LatexRunner._latexmkBaseCommand.concat [
			"-pdfdvi",
			Path.join("$COMPILE_DIR", mainFile)
		]

	_xelatexCommand: (mainFile) ->
		LatexRunner._latexmkBaseCommand.concat [
			"-xelatex",
			Path.join("$COMPILE_DIR", mainFile)
		]

	_lualatexCommand: (mainFile) ->
		LatexRunner._latexmkBaseCommand.concat [
			"-lualatex",
			Path.join("$COMPILE_DIR", mainFile)
		]

