#!/bin/bash
#
#  ccfind - tool to find circular complete sequence by detecting terminal redundancy
#
#    Copyright: 2017 (C) Yosuke Nishimura (yosuke@kuicr.kyoto-u.ac.jp)
#    License: MIT license
#    Initial version: 2017-01-25
#

PROGNAME=$(basename $0)
VERSION="1.1"


# {{{ usage
read -r -d '' usage <<EOF
=== $PROGNAME version $VERSION ===

[description]
$PROGNAME - tool to find circular complete sequence by detecting terminal redundancy

$PROGNAME is originally designed to find circular complete contigs/scaffolds generated by the SPAdes assembler. 
$PROGNAME may be applicable for sequences generated by other assemblers, but not tested.

[dependencies]
- ssearch36        -- included in the FASTA program version 36
                      (http://fasta.bioch.virginia.edu/fasta_www2/fasta_list2.shtml)
- ruby (ver >=2.0) 

[usage]
$ $PROGNAME <input fasta> <output dir> [-i <min %identity> -l <min aligned len> -L <terminal fragment size>]

[options]
    -h, --help
    -v, --version
    -i, --min-percent-identity    [int] (default: 94)
    -l, --min-aligned-length      [int] (default: 50)
    -L, --terminal-fragment-size  [int] (default: 500)

[output files]
result/05.circ.detected.out -- list of sequences with TR
result/05.circ.noTR.fasta   -- modified input sequences by removing TR in the end of sequence.

Please note that very short sequences that are less than 2 x terminal fragment size (1,000 nt by default) will not be tested.
These sequences are logged in the file: result/01.skipped.list
EOF
# }}} usage


# {{{ parse options
for OPT in "$@"
do
	case "$OPT" in
		'-h'|'--help' )
			echo "$usage"
			exit 1
			;;
		'-v'|'--version' )
			echo $VERSION
			exit 1
			;;
		'-i'|'--min-percent-identity' )
			if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]] ; then
				echo "$PROGNAME: option requires an argument -- $1" 1>&2
				exit 1
			fi
			Idt="$2"
			shift 2
			;;
		'-l'|'--min-aligned-length' )
			if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]] ; then
				echo "$PROGNAME: option requires an argument -- $1" 1>&2
				exit 1
			fi
			Len="$2"
			shift 2
			;;
		'-L'|'--terminal-fragment-size' )
			if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]] ; then
				echo "$PROGNAME: option requires an argument -- $1" 1>&2
				exit 1
			fi
			Size="$2"
			shift 2
			;;
		'--'|'-' )
			shift 1
			params+=( "$@" )
			break
			;;
		-*)
			echo "$PROGNAME: illegal option -- '$(echo $1 | sed 's/^-*//')'" 1>&2
			exit 1
			;;
		*)
			if [[ ! -z "$1" ]] && [[ ! "$1" =~ ^-+ ]] ; then
				#params=( ${params[@]} "$1" )
				params+=( "$1" )
				shift 1
			fi
			;;
	esac
done
if [ -z $params ] || [ ${#params[@]} -lt 2 ] ; then
	echo "[error] need 2 arguments" 1>&2
	echo 
	echo "$usage" 1>&2
	exit 1
elif ! [ -f "${params[0]}" ] ; then
	echo "[error] first argument should be a fasta file." 1>&2
	echo 
	echo "$usage" 1>&2
	exit 1
elif [ -e "${params[1]}" ] ; then
	echo "[error] output directory is already exist." 1>&2
	echo 
	echo "$usage" 1>&2
	exit 1
fi
# }}} parse options


### check availablity of ssearch36
command -v ssearch36 >/dev/null 2>&1 || { echo >&2 "ssearch36 is required but not available.  Aborting."; exit 1; }

### check ruby version
ST=`ruby -e 'print RUBY_VERSION.to_f >= 2.0 ? 0 : 1'`
if [ $ST -ne 0 ]; then 
	echo >&2 "ruby (version >=2.0) is required.  Aborting."; exit 1;
fi

### parse args and default params
fin=${params[0]}
dir=${params[1]}
Idt="${Idt:-94}"
Len="${Len:-50}"
Size="${Size:-500}"

### rakefile and log directory
pushd `dirname $0` > /dev/null
scrdir=`pwd -P`
popd > /dev/null
jobname=`basename $0`
rakefile=$scrdir/$jobname.rake
logdir=$dir/log
mkdir -p $logdir

### main
if [ -d $logdir ]; then
	rake 01.make_term_fasta          -f $rakefile dir="$dir" fin="$fin" Size="$Size"            >$logdir/01.stdout 2>$logdir/01.stderr; ST=$?; echo $ST >$logdir/01.exitst
fi
if [ $ST -eq 0 ]; then 
	rake 02.ssearch                  -f $rakefile dir="$dir"                                    >$logdir/02.stdout 2>$logdir/02.stderr; ST=$?; echo $ST >$logdir/02.exitst
fi
if [ $ST -eq 0 ]; then 
	rake 03.parse_ssearch            -f $rakefile dir="$dir"                         Len="$Len" >$logdir/03.stdout 2>$logdir/03.stderr; ST=$?; echo $ST >$logdir/03.exitst
fi
if [ $ST -eq 0 ]; then 
	rake 04.aln_extend_to_term       -f $rakefile dir="$dir"            Size="$Size"            >$logdir/04.stdout 2>$logdir/04.stderr; ST=$?; echo $ST >$logdir/04.exitst
fi
if [ $ST -eq 0 ]; then 
	rake 05.make_circ_list_and_fasta -f $rakefile dir="$dir" fin="$fin" Size="$Size" Idt="$Idt" >$logdir/05.stdout 2>$logdir/05.stderr; ST=$?; echo $ST >$logdir/05.exitst
fi

if [ $ST -eq 0 ]; then 
	echo "finished at: $(LC_ALL=C date)" > $logdir/success
else
	echo "[error] something wrong" 1>&2
	echo "Please check log dir -- $logdir"
	echo "finished at: $(LC_ALL=C date)" > $logdir/error
	exit 1
fi
