#!/usr/bin/env Rscript
## A class that contains bam file information
## Copyright 2014, Sahil Seth
## licence: MIT
## sahil.seth@me.com
## A few functions to supplement those already in this package.
## URL: github.com/sahilseth/rfun
## URL: docs.flowr.space
#### -----------------------

## -------- incase of issues switch on verbose to see what is going on !
verbose=FALSE
nm = "flowr"

get_params <- function(paramPairs){
	func <- as.character(paramPairs[1])
	if(length(func) == 0) return(help())

	args <- formals(func)
	paramPairs <- paramPairs[grep("=", paramPairs)] ## get those with =
	#print("args:");print(args)
	#print("paramPairs:");print(paramPairs)
	#args_supplied = sapply(strsplit(paramPairs, "="), "[[", 1)


	if(verbose) message("We have ",length(paramPairs)," parameters\n")
	for(param in paramPairs){
		temp <- unlist(strsplit(param, "="));
		nm = gsub("-", "", temp[1])
		value=temp[2]
		value <- strsplit(value,",")[[1]] #handling those with , in value.. for multiple R values

		## --- if function supports ... need to pass ALL arguments
		if(sum(names(args) %in% "...") & !nm %in% names(args)){
			## -- remove the dots argument
			dots = which(names(args) == "...")
			args = args[-dots]
			message("Adding ", nm, ":", value)
			l = list(nm = value);names(l) = nm
			args <- c(args, l)
		}

		if(class(args[[nm]]) == "numeric" ){
			args[[nm]] = as.numeric(value)
		}else if(class(args[[nm]]) %in% c("character", "name" )){
			args[[nm]] = as.character(value)
		}else if(class(args[[nm]]) %in% c("logical")){
			args[[nm]] = as.logical(value)
		}else if(class(args[[nm]]) %in% c("list")){
			args[[nm]] = as.list(value)
		}else if(class(args[[nm]]) %in% c("call")){ ## example call to getOption
			args[[nm]] = as.character(value)
		}
		#print(args)
	}


	##print(do.call(rbind, as.list(args)))
	if(verbose) print(args)
	return(as.list(args))
}


flow_help <- function(){
	cmds <- matrix(c(
		'run',     'Running predefined pipelines; try flowr avail x="pipelines',
		"avail",    "Checking what modules and pipelines are available; avail x=modules OR avail x=pipelines",
		'status',   'Detailed status of a flow (s).',
		'rerun_flow',     'rerun a previously failed flow',
		'kill_flow',     'Kill the flow, upon providing working directory'
	), byrow=T, ncol=2)
	#cat("\nThis interface allows shell access to all functions in package flowr (and beyond).")
	cat(sprintf("\n  %-15s %s", cmds[,1], cmds[,2]), sep="")
}

generic_help <- function(){
	cat(sprintf("\nUsage: %s function [arguments]\n", nm))
	#cat("\nFunctions where the arguments are simple objects like numeric/character/logical can be called.",
	#		"\nLists become a little more complicated. say x=a,b is converted to a list with elements a,b\n",
	#		"\nSome examples:")
	#}else{
	#cat("\n## Fetch some numbers:\nrfun rnorm n=100",
	#			"\n## Fetch files from pacakges:",
	#		"\nrmd=$(rfun system.file package=knitr ...=examples/knitr-minimal.Rmd)",
	#		"\necho $rmd",
	#		"\n## knit this awesome example !",
	#		"\nrfun knitr::knit input=$rmd\n")
	#}
	if(nm == "flowr")
		flow_help()
	cat(sprintf("\n\nPlease use '%s function -h' to obtain further information about the usage.\n", nm))
}


main <- function(){
	args <- commandArgs(trailingOnly = TRUE)

	##-------- if default function is not in the space, load flowr library
	if(nm == "flowr")
		require(flowr, quietly=!verbose, warn.conflicts=verbose)

	## -------------- Load the required package
	if(grepl("::", args[1])){
		pkg <- gsub("(.?)::.*", "\\1", args[1])
		cat("loading pkg:", pkg, "\n");
		library(pkg, character.only = TRUE)
		args[1] = as.character(gsub(".*::(.*)", "\\1", args[1]))
	}

	if(is.na(args[1])){
		generic_help()
	}else if(args[1] == "-h"){
		generic_help()
	}else if(is.na(args[2])){
		help(args[1])
	}else if(args[2] == "-h"){
		help(args[1])
	}else{
		params <- get_params(args)
		if(verbose){
			cat("\nStarting",args[1],"with params\n",
				paste(names(params), unlist(params),sep=": ",
					collapse="\n"),"\n")
			#print(args)
			if(verbose) print(str(params))
		}
		#cat("Calling:", args[1])
		out <- do.call(args[1], args = params)
		return(out)
	}
}


out = main()

## --- showing the output of the returned..
if(is.data.frame(out)){
	message("Showing a head of the data.frame")
	print(head(out))
}else if(is.null(out)){
	cat("")
}else if(is.list(out)){
	print(out)
}else if(is.atomic(out)){
	print(cat(out, "\n"))
}else{
	cat("")
}



if(FALSE){
	## tests
	paramPairs=c('bwa', 'fqs1=sample1.fq', 'bwa_index=index', 'bwa_samse_opts=myopts')
	debug(get_params)
	get_params(paramPairs)

}

if(verbose) warnings()
