#!/usr/bin/env bash
#
# Copyright (c) 2016 10x Genomics, Inc. All rights reserved.
#
# Common helper functions, docopt strings, options processing functions,
# and sample_def generation functions.
#

###########################################################
# Helper functions
#
function error {
    echo -e "[error] $1"
    exit 1
}

function warn {
    echo -e "[warn] $1"
}

function abspath {
    eval path=$1
    if [[ "$path" = /* ]]; then
        echo $path
    else
        echo $(pwd)/$path
    fi
}

function print_help {
    echo -e "$USAGE"
    exit 0
}

function sourceme {
    SOURCEME=$TENX_SCRIPTDIR/../../../sourceme.bash
    source $SOURCEME 2> /dev/null
}

###########################################################
# Shared docopt strings
#
read -d '' DOCOPT_PREAMBLE_FASTQS <<EOF
The commands below should be preceded by '$TENX_PRODUCT':

Usage:
    $TENX_SUBCMD
        --id=ID
        --fastqs=PATH
        [--sample=PREFIX]
        [options]
    $TENX_SUBCMD <run_id> <mro> [options]
    $TENX_SUBCMD -h | --help | --version

Arguments:
    id      A unique run id, used to name output folder [a-zA-Z0-9_-]+.
    fastqs  Path of folder created by mkfastq or bcl2fastq.
    sample  Prefix of the filenames of FASTQs to select.
EOF



read -d '' DOCOPT_OPTIONS_FASTQS <<EOF
    --lanes=NUMS        Comma-separated lane numbers.
    --indices=INDICES   Comma-separated sample index set "SI-001" or sequences.
    --project=TEXT      Name of the project folder within a mkfastq or
                            bcl2fastq-generated folder to pick FASTQs from.
EOF

read -d '' DOCOPT_OPTIONS_MRP_CLUSTER <<EOF
    --jobmode=MODE      Job manager to use. Valid options:
                            local (default), sge, lsf, or a .template file
    --localcores=NUM    Set max cores the pipeline may request at one time.
                            Only applies when --jobmode=local.
    --localmem=NUM      Set max GB the pipeline may request at one time.
                            Only applies when --jobmode=local.
    --mempercore=NUM    Set max GB each job may use at one time.
                            Only applies in cluster jobmodes.
    --maxjobs=NUM       Set max jobs submitted to cluster at one time.
                            Only applies in cluster jobmodes.
    --jobinterval=NUM   Set delay between submitting jobs to cluster, in ms.
                            Only applies in cluster jobmodes.
    --overrides=PATH    The path to a JSON file that specifies stage-level
                            overrides for cores and memory.  Finer-grained
                            than --localcores, --mempercore and --localmem.
                            Consult the 10x support website for an example
                            override file.
EOF

read -d '' DOCOPT_OPTIONS_MRP <<EOF
    --uiport=PORT       Serve web UI at http://localhost:PORT
    --disable-ui        Do not serve the UI.
    --noexit            Keep web UI running after pipestance completes or fails.
    --nopreflight       Skip preflight checks.
EOF

read -d '' DOCOPT_OPTIONS_FOOTER <<EOF
    -h --help           Show this message.
    --version           Show version.

Note: '$TENX_PRODUCT $TENX_SUBCMD' can be called in two ways, depending on how you
demultiplexed your BCL data into FASTQ files.

1. If you demultiplexed with '$TENX_PRODUCT mkfastq' or directly with
   Illumina bcl2fastq, then set --fastqs to the project folder containing
   FASTQ files. In addition, set --sample to the name prefixed to the FASTQ
   files comprising your sample. For example, if your FASTQs are named:
       subject1_S1_L001_R1_001.fastq.gz
   then set --sample=subject1

2. If you demultiplexed with '$TENX_PRODUCT demux', then set --fastqs to a
   demux output folder containing FASTQ files. Use the --lanes and --indices
   options to specify which FASTQ reads comprise your sample.
   This method is deprecated. Please use '$TENX_PRODUCT mkfastq' going forward.
EOF

###########################################################
# Shared options processing and sample_defs generator functions
#
function generate_sample_defs_fastqs_crg {
    sample_def=""
    for fastq in $fastqs; do
        sample_def="$sample_def
        {
            \"gem_group\": null,
            \"lanes\": $lanes,
            \"read_path\": \"$fastq\",
            \"sample_indices\": $indices,
            \"sample_names\": $sample_names,
            \"library\": $library,
            \"bc_in_read\": 1,
            \"bc_length\": 16
        },"
    done
    sample_def=${sample_def%\,}
    sample_def=$(echo -e "[ $sample_def\n    ]")
}

function process_options_fastqs {
    # Re-write any paths that came directly from demux/mkfastq pipestances into
    # pipeline-compatible paths -- result will still be comma-delimited list.
    if [ -n "$fastqs" ]; then
        if [ -n "$project" ]; then
            fastqs=$(check_fastq_paths --fastqs=$fastqs --project=$project)
            fastq_code=$?
        else
            fastqs=$(check_fastq_paths --fastqs=$fastqs)
            fastq_code=$?
        fi
        if [[ $fastq_code -ne 0 ]]; then
            exit $fastq_code
        fi
     fi

    # Auto-detect input mode, fastqs, correct fastqprefix from supplied args
    if [ -n "$fastqs" ]; then
        if [ -n "$sample" ]; then
            fastq_mro_args=( $(check_fastq_params --fastqs=$fastqs --fastqprefix=$sample) )
            fastq_code=$?
        else
            fastq_mro_args=( $(check_fastq_params --fastqs=$fastqs) )
            fastq_code=$?
        fi
        if [[ $fastq_code -ne 0 ]]; then
            exit $fastq_code
        fi
        fastq_mode=\"${fastq_mro_args[0]}\"
        sample=${fastq_mro_args[1]}
    fi

    # --fastqs
    # Build array for later sample_def generation
    if [ -n "$fastqs" ]; then
        _fastqs=${fastqs//\,/\ }
        fastqs=""
        for _fastq in $_fastqs; do
           fastqs="$fastqs $(abspath $_fastq)"
        done
    fi

    # --sample
    # Build array of sample prefixes (normally single, array not advertised)
    sample_names=null
    if [ -n "$sample" ]; then
        sample_names=${sample//\,/\"\,\"}
        sample_names=\[\ \"$sample_names\"\ \]
    fi

    # --library
    if [ -n "$library" ]; then
        library=\"$library\"
    else
        # consistent with pipeline missing param behavior
        library=\"LibraryNotSpecified\"
    fi

    # --indices (double-quote, arrayize)
    if [ -n "$indices" ]; then
        indices=${indices//\,/\"\,\"}
        indices=\[\ \"$indices\"\ \]
    else
        indices=\[\ \"any\"\ \]
    fi

    # --lanes (double-quote, arrayize)
    if [ -n "$lanes" ]; then
        lanes=${lanes//\,/\"\,\"}
        lanes=\[\ \"$lanes\"\ \]
    else
        lanes=null
    fi
}
