#!/usr/bin/env perl

=head1 LICENSE

Copyright (c) 2007-2009 Illumina, Inc.

This software is covered by the "Illumina Genome Analyzer Software
License Agreement" and the "Illumina Source Code License Agreement",
and certain third party copyright/licenses, and any user of this
source file is bound by the terms therein (see accompanying files
Illumina_Genome_Analyzer_Software_License_Agreement.pdf and
Illumina_Source_Code_License_Agreement.pdf and third party
copyright/license notices).

This file is part of the Consensus Assessment of Sequence And VAriation
(CASAVA) software package.

=head1 NAME

configureBuild.pl

=head1 DIAGNOSTICS

=head2 Exit status

0: successful completion
1: abnormal completion
2: fatal error

=head2 Errors

All error messages are prefixed with "ERROR: ".

=head2 Warnings

All warning messages generated by CASAVA are prefixed with "WARNING: ".

=head1 CONFIGURATION AND ENVIRONMENT

=back

=head1 BUGS AND LIMITATIONS

There are no known bugs in this module.

All documented features are fully implemented.

Please report problems to Illumina Technical Support (support@illumina.com)

Patches are welcome.

=head1 AUTHOR

Richard Carter, Lukasz Szajkowski

=cut

use warnings FATAL => 'all';
use strict;
use Cwd qw(abs_path);
use POSIX qw(strftime);
use IO::File;
use Carp;

use Pod::Usage;
use Getopt::Long;
use lib '@CASAVA_FULL_PERL_LIBDIR@';

# import the field descriptors for the current Export Files
use Casava::Common::Log;
use Casava::Common::IOLib
  qw(executeCmd getProcessorsCount);
use Casava::TaskManager qw(checkPointInit addEverything2CheckPoint executeSingleTask executeCheckPoint);
use Casava::Common::Utils qw(reallyRealPath);
use Casava::PostAlignment::Sequencing::Config qw(%CONF_APP %CONF_PROJ %CONF_RUN
  %runsConfig %chrEnds addExportFiles configureSampleDirectories
  configureTargets updateRunConfValue configureDirectories readProjectParameters);

use Casava::PostAlignment::Sequencing::WorkflowManagement;
use Casava::PostAlignment::Plugins qw(targetExecuteOrGenerateWorkflow);

my $VERSION = '@CASAVA_VERSION_FULL@';

my $programName = (File::Spec->splitpath($0))[2];
my $Version_text =
    "$programName $VERSION\n"
  . "Copyright (c) 2008, 2009 Illumina\n"
  . "This source file is covered by the \"Illumina Public Source License\"\n"
  . "agreement and bound by the terms therein.\n";

 my %showTargets;
 {
     # these targets are already documented:
     my @primaryTargets = ('sort','assembleIndels','callSmallVariants','rnaCounts','bam','gsIndex');
     # user should not have to call these targets individually:
     my @hiddenTargets = ('configure','refSeq','refSeqClean');
     %showTargets = map { $_ => undef } Casava::PostAlignment::Plugins::listTargets();
     for (@primaryTargets,@hiddenTargets) {
         if(exists $showTargets{$_}) { delete $showTargets{$_}; }
     }
 }

my $usage =
    "Usage: $programName [options]\n"
  . "\t-id, --inSampleDir=PATH    - PATH to the aligned sample input directory\n"
  . "\t-od, --outDir=PATH   - PATH to the build sample output directory\n"
  . "\t-ref, --refSequences=PATH  - PATH of the reference genome sequences\n"
  . "\t--samtoolsRefFile=FILE     - PATH to a single samtools-style reference file\n"
  . "\nOPTIONAL (BEHAVIOUR)\n"
  . "\t-a, --applicationType=TYPE - type of analysis [DNA, RNA] default DNA\n"
  . "\t--postRunCmd=CMDLINE       - executes CMDLINE after all tasks are finished\n"
  . "\t-f, --force                - ignore errors from previous run\n"
  . "\t--help[=TARGET]            - prints usage guide. If TARGET is specified, prints usage guide for that target\n"
#  . "\t-rt, --removeTemps=ON/OFF  - removes temporary data (default ON)\n"
  . "\t--tempDir                  - overrides default path for local temporary files\n"
  . "\t--targets LIST             - space-separated LIST of targets to run (default: all)\n"
  . "\t-w, --workflow             - instead of running the program generates the workflow definition file.\n"
  . "\t-wa, --workflowAuto        - generates the workflow definition file and runs it. See --jobsLimit.\n"
  . "\t-sa, --sgeAuto             - generates the workflow definition file and runs it on SGE (use with --sgeQueue)\n"
  . "\t--jobsLimit                - limit number of parallel jobs. Defaults: -1 (unlimited) for --sgeAuto. 1 for --workflowAuto.\n"
  . "\t--sgeQueue                 - SGE queue name - used with --sgeAuto or --workflow (e.g: all.q)\n"
  . "\t--sgeQsubFlags             - Extra parameters to be passed to SGE qsub by the taskServer.pl\n"
  . "\t--workflowFile=FILE        - overrides workflow file name. (default workflow.<date>.txt)\n"
  . "\t--verbose=NUMBER           - sets the console log verbose level (default 0 - minimum)\n"
  . "\t--version                  - prints version information\n"
  . "\nOPTIONAL (ANALYSIS)\n"
#  . "\t--spliceJunction=NAME      - NAME of splice junction set relative to --genesListPath\n"
#  . "\t--featureFileName=FILE     - FILE name of exons definition file relative to --genesListPath\n"
#  . "\t--genesListPath=PATH       - PATH of the reference sequences for genes \n"
  . "\t--refFlatFile=PATH         - PATH to UCSC refFlat.txt.gz file. The file must be gz-compressed.\n"
  . "\t--seqGeneMdFile=PATH       - PATH to NCBI seq_gene.md.gz file. The file must be gz-compressed.\n"
  . "\t--sortKeepAllReads         - Keep all purity filtered, duplicate and unmapped reads in the build.\n"
  . "\t                                 These reads will be ignored during variant calling.\n"
  . "\t--read                     - Limit input to the specified read only. Forces single-ended analysis\n"
  . "\t                                 on one read of a double-ended dataset.\n"
#  . "\t--snpThreshold=NUMBER      - sets the SNPCaller primary allele threshold to NUMBER (default 10)\n"
#  . "\t--snpThreshold2=NUMBER     - sets the SNPCaller secondary allele threshold to NUMBER (default 6)\n"
#  . "\t--snpMaxRatio=NUMBER       - sets the SNPCaller max ratio to NUMBER (default 3)\n"
#  . "\t--snpCovCutoff=NUMBER      - sets the SNPCaller coverage cutoff depth to NUMBER times the chromosomal mean. (default 3)\n"
#  . "\t                               Set this value to -1 to disable the coverage filter (recommended for RNA and targeted resequencing)\n"
#  . "\t-rm, --readMode            - Runread-mode for all runs [paired, single] (default paired)\n"
  . "\t--QVCutoff=NUMBER          - Sets the paired-end aligment score threshold to NUMBER (default 90)\n"
  . "\t--QVCutoffSingle=NUMBER    - Sets the single-read aligment score threshold to NUMBER (default 10)\n"
  . "\t--singleScoreForPE=VALUE   - Sets the variant caller to filter reads with single score below QVCutoffSingle\n"
  . "\t                                 in PE mode YES|NO (default NO)\n"
  . "\t--ignoreUnanchored         - Ignore unanchored read pairs in indel assembly and variant calling. Unanchored\n"
  . "\t                                 read pairs have a single-read alignment score of 0 for both reads.\n"
#  . "\t--baseQualityCutOff=NUMBER - sets minimum base quality in allele caller (default 0)\n"
#  . "\t--qualityType=VALUE        - Quality to probability scheme Phred64|Solexa64 (default Phred64)\n"
#  . "\t--skipVariableMetadata     - Remove certain meta-data from output files\n"
  . "\t--toNMScore=NUMBER         - Minimum single-read alignment score to put a read to NM (default -1 - off)\n"
#  . "\t--denseAlleleCalls         - Leave empty rows out of the allele-call file (already set for RNA analysis)\n"
#  . "\t--readSampleRateInput=VALUE - VALUE in range (0, 1]. Indicates fraction of input reads to consider for build.\n"
#  . "\t--dataSetSuffix=STRING     - IndelFinder.pl, alleleCaller and SVFinder output file suffix (default \"\")\n"
#  . "OPTIONAL (R&D - not supported)\n"
#  . "\t-readSampleRateStart=VALUE - Start VALUE in range (0, 1]. Indicates fraction of reads to consider for allele and SNP calling\n"
#  . "\t-readSampleRateEnd=VALUE   - End VALUE in range (0, 1]. Indicates fraction of reads to consider for allele and SNP calling (End value must be >= Start value)\n"
#  . "\t-readSampleRateStep=VALUE  - Step VALUE in range (0, 1] default is 0.1. CASAVA will create allele and snp workflows for all values in range [readSampleRateStart,readSampleRateEnd] with readSampleRateStep\n"  
#  . "\t--frc=VALUE               - produce sort.count for forward and reverce strand YES|NO (default NO)\n"
#  . "OPTIONAL (R&D - SV not supported)\n"
#  . "\t--maxSD=NUMBER             - SV\n"
#  . "\t--minObservations=NUMBER   - SV\n"
#  . "\t--maxFragmentSize=NUMBER   - SV\n"
#  . "\t--minSingleReadScore=NUMBER- SV\n"
#  . "\t--numLongSD=NUMBER         - SV\n"
#  . "\t--numShortSD=NUMBER        - SV\n"
  . "PRIMARY TARGETS:\n"
  . "\tall               - Run all pre-configured targets for the given analysis type (default).\n"
  . "\tsort              - Bin reads and sort by position; Remove PCR duplicates for paired-end data.\n"
  . "\tassembleIndels    - Search for candidate indels from paired-end reads via de-novo assembly of\n"
  . "\t                        contigs which are aligned back to the reference.\n"
  . "\tcallSmallVariants - Call snps and indels from locally re-aligned reads. Candidate indels\n"
  . "\t                        from the assembleIndels target can be used to improve indel results.\n"
  . "\trnaCounts         - Calcuate gene and exon counts in an RNA-Seq build.\n"
  . "\tbam               - Aggregate all reads into a single BAM file with chromosome re-labeling.\n"
  . "\tgsIndex           - Pre-compute Genome Studio linear index for all reads in the build.\n"
#  . "\tlistRuns                   - lists all runs in the configuration\n"
#  . "\tremoveRun                  - removes run from the configuration\n"
#  . "\texp2sra                    - converts all export files from GERALD folders to a zipped fastq files and generates sra.xml\n"
#  . "\tclean                      - soft clean - allows to restart the build without removing project.conf and run.conf.xml\n"
#  . "\tallClean                   - removes all data\n"
#  . "\tsortClean                  - removes sort data\n"
  . (scalar(keys( %showTargets)) ? "ADDITIONAL TARGETS:\n" : '')
  . join('', map { "\t" . $_ ."\n" } (sort keys %showTargets))
  . "TARGET DOCUMENTATION:\n"
  . "\tUse ./configureBuild.pl --help <target> for target usage and documentation\n\n"

.<<'EXAMPLES_END';
EXAMPLES:

#Run example paired DNA analysis
@CASAVA_FULL_BINDIR@/configureBuild.pl --outDir ./Build_Project_FC626BWAAXX_Sample_lane4 \
 --inSampleDir @CASAVA_FULL_DATADIR@/examples/Validation/Default/Aligned/Project_FC626BWAAXX/Sample_lane4 \
 --samtoolsRefFile @CASAVA_FULL_DATADIR@/examples/Validation/100723_EAS346_0188_FC626BWAAXX/Data/Intensities/BaseCalls/controls.fasta

#Run example single-ended DNA analysis
@CASAVA_FULL_BINDIR@/configureBuild.pl --outDir ./Build_Project_FC626BWAAXX_Sample_lane8 \
 --inSampleDir @CASAVA_FULL_DATADIR@/examples/Validation/Default/Aligned/Project_FC626BWAAXX/Sample_lane8 \
 --samtoolsRefFile @CASAVA_FULL_DATADIR@/examples/Validation/100723_EAS346_0188_FC626BWAAXX/Data/Intensities/BaseCalls/controls.fasta

#Run example single-ended RNA analysis
@CASAVA_FULL_BINDIR@/configureRnaBuild.pl --outDir ./Build_Project_Demo_Sample_AR008 \
 --inSampleDir @CASAVA_FULL_DATADIR@/examples/Validation/110120_P20_0993_A805CKABXX/Aligned/Project_Demo/Sample_AR008 \
 --samtoolsRefFile @CASAVA_FULL_DATADIR@/examples/iGenomes/Homo_sapiens/UCSC/hg18/Sequence/Chromosomes/chr22.fa \
 --refFlatFile @CASAVA_FULL_DATADIR@/examples/iGenomes/Homo_sapiens/UCSC/hg18/Annotation/Genes/refFlat.txt.gz

EXAMPLES_END

my @alignSampleDirs  = ();
my $buildDir         = "";
my @targets          = ();
my @readMode         = ();
my $help             = 'nohelp';
my $noColorLog       = 0;
my $isVersion        = 0;
my %PARAMS           = ();
my %CURRENT_PROJECT_CONF = ();
$CURRENT_PROJECT_CONF{force} = 0;

my $argvStr = join ' ', @ARGV;
Getopt::Long::Configure('permute');
$PARAMS{appVersion} = $VERSION;

$PARAMS{verbose} = 0;

initLog( undef, 4, 0 ); #log everything to stderr until we get projectDir and verbose level

my $result = GetOptions(
    'noColorLog'            => \$noColorLog,
    "applicationType|a=s"   => \$PARAMS{applicationType},
    "inSampleDir|id=s@"     => \@alignSampleDirs,
    "outDir|od=s"           => \$buildDir,
#    "buildDir|b=s"          => \$PARAMS{dirBuild},
    "configFile=s"          => \$PARAMS{configFile},
    "currentStatus=s"       => \$CURRENT_PROJECT_CONF{currentStatus},
#    "dirBuildExport=s"     => \$PARAMS{dirBuildParsed},
    "force|f"               => \$CURRENT_PROJECT_CONF{force},
    "read=i"                => \$PARAMS{read},
    "lanes=s"               => \$PARAMS{lanes},
    "barcodes=s"            => \$PARAMS{barcodes},
    "refSequences|ref=s"    => \$PARAMS{dirRefSeq},
    'maskRefSeqFiles=s'     => \$PARAMS{maskRefSeqFiles},
    "chromNameSource=s"     => \$PARAMS{chromNameSource},
    "chromNameValidation=s" => \$PARAMS{chromNameValidation},
    "samtoolsRefFile=s"     => \$PARAMS{samtoolsRefFile},
    "dirUcscGaps|gaps=s"    => \$PARAMS{dirUcscGaps},
    "genesListPath|genes=s" => \$PARAMS{genesListPath},
    "parsedDir=s"           => \$PARAMS{parsedDir},
    "target|t=s@"           => \@targets, #backward compatibility for specifying targets as multiple -t arguments
    "targets:s{,}"          => \@targets, #advertised way of supplying as --targets configure poisson sv 
    #"readMode|rm=s@"        => \@readMode,
#    "frc=s"                 => \$PARAMS{frc},
    "spliceJunction|spj=s"  => \$PARAMS{spliceJunction},
    "featureFileName|ffn=s" => \$PARAMS{featureFileName},
    "numberOfProcesses|n=s" => \$PARAMS{jobsLimit}, #backward compatibility.
    "jobsLimit=i"           => \$PARAMS{jobsLimit}, #advertized way
    "snpThreshold=i"        => \$PARAMS{snpThreshold},
    "snpThreshold2=i"       => \$PARAMS{snpThreshold2},
    "snpMaxRatio=i"         => \$PARAMS{snpMaxRatio},
#    "snpCovCutoff=f"        => \$PARAMS{snpCovCutoff},

    "postRunCmd=s"          => \$PARAMS{postRunCmd},
    'readSampleRateStart=f' => \$PARAMS{readSampleRateStart},
    'readSampleRateEnd=f'   => \$PARAMS{readSampleRateEnd},
    'readSampleRateStep=f'  => \$PARAMS{readSampleRateStep},
    'readSampleRateInput=f' => \$PARAMS{readSampleRateInput},
    "QVCutoff=i"            => \$PARAMS{QVCutoff},
    "QVCutoffSingle=i"      => \$PARAMS{QVCutoffSingle},
#    'denseAlleleCalls'      => \$PARAMS{isDenseAlleleCalls},
    "ignoreUnanchored!"     => \$PARAMS{isIgnoreUnanchored},
    "baseQualityCutOff=i"   => \$PARAMS{baseQualityCutOff},
    "removeTemps|rt=s"      => \$PARAMS{removeTemps},
    "tempDir=s"             => \$PARAMS{dirBuildTemp},
    "toNMScore=s"           => \$PARAMS{toNMScore},
    "dataSetSuffix=s"       => \$PARAMS{dataSetSuffix},
    "qualityType=s"         => \$PARAMS{qualityType},
#    "projectDir|p=s"        => \$projectDir,
    "queue|sgeQueue=s"      => \$PARAMS{sgeQueue},
    "sgeQsubFlags=s"        => \$PARAMS{sgeQsubFlags},
    "sgeQmakeFlags=s"       => \$PARAMS{sgeQmakeFlags},
    "task2MakeParams=s"     => \$PARAMS{task2MakeParams},

    "make"                  => \$PARAMS{isWorkflowMake},
    "workflowAuto|wa"       => \$PARAMS{isWorkflowAuto},
    "sgeAuto|sa"            => \$PARAMS{isWorkflowSGE},
    "workflowFile=s"        => \$PARAMS{workflowFile},
    "singleScoreForPE=s"    => \$PARAMS{singleScoreForPE},
    "version"               => \$isVersion,
    "verbose|v=i"           => \$PARAMS{verbose},
    "binSizeProject=i"      => \$PARAMS{binSizeProject},
    "binSizeBuild=i"        => \$PARAMS{binSizeBuild},

    "skipVariableMetadata!" => \$PARAMS{skipVariableMetadata},

    "ignoreMissingMetadata"             => \$PARAMS{ignoreMissingMetadata},
    Casava::PostAlignment::Plugins::getOptionsMapping(%PARAMS),
    "help:s"                            => \$help
);

# display the version info
if ($isVersion) {
    print $Version_text;
    exit(0);
}

# display the help text when no sample directory is given
if ( ( $result == 0 || !$buildDir ) && 'nohelp' eq $help) {
    die "$usage";
}

errorExit("ERROR: Unrecognized command-line argument(s): @ARGV")  if (0 < @ARGV);

# open the CASAVA log file
errorExit("ERROR: unable to interpret the following as an output directory path: $buildDir") unless !reallyRealPath($buildDir);
my $logPath = File::Spec->catfile( $buildDir, "CASAVA.log" );
initLog( $logPath, $PARAMS{verbose}, 4, !$noColorLog);

# display the help text
if ('' eq $help) {
    print $usage;
    exit(0);
} elsif ('nohelp' ne $help) {
    Casava::PostAlignment::Plugins::targetHelpUsage($help);
}

#==============
# configuration
#==============

# TODO: derive the build directory if none is provided

# configure the build directory structure, check reference sequences, etc.
my $confStatus =
  Casava::PostAlignment::Sequencing::Config::configure( $buildDir,
    $argvStr, %CURRENT_PROJECT_CONF, %PARAMS, @targets, @readMode, $usage );

# configure each of the targets
configureTargets( $confStatus, @targets, @alignSampleDirs, $buildDir);

printLog( "Running [$0 " . $argvStr . "]\n", 1 );

#############################################################
# Configuration

my $cmd                 = "";
my $timeStampFormat     = $CONF_APP{formatTimeStamp};
my $unsort_f            = $CONF_APP{f_unsort};
my $exportDir           = $CONF_PROJ{dirBuildExport};
my $parsedDir           = $CONF_PROJ{dirBuildParsed};
my $binDir              = '@CASAVA_FULL_LIBEXECDIR@';
my $dirToMove           = $CONF_APP{dirToMove};
my $reportsCmd          = File::Spec->catfile( '@CASAVA_FULL_LIBEXECDIR@', $CONF_APP{cmdReports} );
my $runSplitCmd         = File::Spec->catfile( $binDir , $CONF_APP{cmdRunSplit} );
my $runExport2FastqCmd  = File::Spec->catfile($binDir , "runExport2Fastq.pl");

#############################################################

my %buildChromsBinSizes = ();
readProjectParameters( %buildChromsBinSizes, "BUILD_BIN_SIZES", $buildDir );

# Activate writing to workflow file
if ( $CONF_PROJ{isWorkflow} == 1 ) {
    printLog( "Workflow ON\n", 2 );
} else {
    printLog( "Workflow OFF\n", 2 );
}

#############################################################

my $prefTarget         = 'start';

foreach my $target (@targets) {
    my $warnings = getWarningsCount();
    updateRunConfValue( 'currentStatus', $target );
    my $targetStatusText;

    if ( $target eq 'export' ) {
        logWarning "$0: Target 'export' has no effect. Export file parsing is now performed by the 'sort' target.\n";
    }    # elsif
    elsif ( $target eq 'allele' ) {
        logWarning "$0: Target 'allele' has no effect. Variant calling is now performed by the 'callSmallVariants' target.\n";
    }    # elsif
    elsif ( $target eq 'snp' ) {
        logWarning "$0: Target 'snp' has no effect. Variant calling is now performed by the 'callSmallVariants' target.\n";
    }    # elsif
    elsif ( $target eq 'exp2sra' ) {
        $cmd = "$runExport2FastqCmd --projectDir=$buildDir --prevTarget=$prefTarget";
        executeCmd($cmd, 4);
    }
    elsif ( $target eq 'reports' ) {
        $cmd = "$reportsCmd  --projectDir=$buildDir";
        executeCmd($cmd, 4);
    }    # elsif
    # elsif ( $target eq 'clean' ) {
    #     print "$build_Current_dir";
    #     $cmd = "$CONF_APP{cmdDelete} -fr "

    #       #          . "$projectDir/conf/project.conf "
    #       . "$CONF_PROJ{currentProjectDir}/$CONF_APP{TAG_NMNM}/ "
    #       . "$CONF_PROJ{currentProjectDir}  "
    #       . "$CONF_PROJ{currentProjectDir}/lanes  "
    #       . "$projectDir/html/*.html "
    #       . "$projectDir/stats/$CONF_APP{f_reads_indx} ";
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);

    #     $cmd = "$CONF_APP{cmdDelete} -fr ";
    #     foreach my $chrom (@chroms) {
    #         $cmd .= "$currentProjectDir/$chrom/ ";
    #     }
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);
    #     foreach my $chrom (@chroms) {
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -f "
    #           . "$build_Current_dir/$chrom/*/$unsort_f";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #         $cmd =
    #           "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sorted.txt;"
    #           . "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sort.txt;"
    #           . "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sort.merge.*";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -fr $currentProjectDir/$chrom/*/corect* "
    #           . "$currentProjectDir/$chrom/*/sort.split.* "
    #           . "$currentProjectDir/$chrom/*/$dirToMove/";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #     }
    # }    # elsif
    # elsif ( $target eq 'allClean' ) {
    #     print "$build_Current_dir";
    #     $cmd =
    #         "$CONF_APP{cmdDelete} -fr "
    #       . "$build_Current_dir $projectDir/conf/ $projectDir/lanes/ "
    #       . "$CONF_PROJ{currentProjectDir}/$CONF_APP{TAG_NMNM}/ "
    #       . "$CONF_PROJ{currentProjectDir} "
    #       . "$projectDir/stats/ "
    #       . "$projectDir/html/ "
    #       . "$projectDir/stats/$CONF_APP{f_reads_indx} ";
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);

    #     #."$build_Current_dir $projectDir$dup_dir/* "
    #     #.    "$projectDir$dup_dir/*";
    #     $cmd = "$CONF_APP{cmdDelete} -fr ";
    #     foreach my $chrom (@chroms) {
    #         $cmd .= "$build_Current_dir $currentProjectDir/$chrom/";
    #     }
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);
    # }    # elsif
    # elsif ( $target eq 'alleleClean' ) {
    #     $cmd =
    #         "$CONF_APP{cmdDelete} -fr $build_Current_dir/*/*/"
    #       . " $build_Current_dir/*/*/allele.start"
    #       . " $build_Current_dir/*/*/allele.finished"
    #       . " $build_Current_dir/*/*/$CONF_APP{f_allele_sort}";
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);
    # }    # elsif
    # elsif ( $target eq 'snpClean' ) {
    #     foreach my $chrom (@chroms) {
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -f "
    #           . " $build_Current_dir/$chrom/*/snpStats*.txt"
    #           . " $build_Current_dir/$chrom/*/coverage*.txt";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #     }
    #     $cmd = "$CONF_APP{cmdDelete} -f " . "$build_Current_dir/*/*.snp*.txt";
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);
    # }    # elsif
    # elsif ( $target eq 'splitClean' ) {
    #     $cmd =
    #         "$CONF_APP{cmdDelete} -fr $build_Current_dir/*/*/sort.txt "
    #       . "$build_Current_dir/*/*/corect* $build_Current_dir/*/*/$dirToMove/";
    #     print $cmd . "\n";
    #     executeCmd($cmd, 4);
    # }    # elsif
    # elsif ( $target eq 'sortClean' ) {
    #     foreach my $chrom (@chroms) {
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -f "
    #           . "$build_Current_dir/$chrom/*/$unsort_f";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sorted.txt"
    #           . "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sort.txt"
    #           . "$CONF_APP{cmdDelete} -f $build_Current_dir/$chrom/*/sort.merge.*";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #         $cmd =
    #             "$CONF_APP{cmdDelete} -fr $currentProjectDir/$chrom/*/corect* "
    #           . "$currentProjectDir/$chrom/*/sort.split.* "
    #           . "$currentProjectDir/$chrom/*/$dirToMove/";
    #         print $cmd . "\n";
    #         executeCmd($cmd, 4);
    #     }
    # }    # elsif
    elsif ( $target eq 'duplicates' ) {
        logWarning "$0: Target 'duplicates' has no effect. Duplicate removal is now performed by the 'sort' target.\n";
    }
    elsif ($target ne 'continue') {
        $targetStatusText = targetExecuteOrGenerateWorkflow($target, $prefTarget, $buildDir, %buildChromsBinSizes);
        errorExit "$0:ERROR: unknown target $target\n" if 'unknown' eq $targetStatusText;
    }
    $prefTarget = $target;

    my $statusText = (getWarningsCount() == $warnings) ? 
                        ($targetStatusText ? $targetStatusText : 'OK') : 
                        'WARNINGS';
    my $status = (getWarningsCount() == $warnings) ? 'info' : 'warning';
    printLog( sprintf ("TARGET %-40s[$statusText]\n", $target), 0 ,  $status);

}    # foreach

if (defined $PARAMS{postRunCmd})
{
    my $checkPointRef  = checkPointInit( "ALL_DONE", "The checkpoint that gets executed after everything is done" );
    addEverything2CheckPoint (%{$checkPointRef});
    executeCheckPoint(%{$checkPointRef});
    executeSingleTask( "cd $buildDir"
                       .' && CASAVA_FULL_ETCDIR="@CASAVA_FULL_ETCDIR@" '
                           .'CASAVA_FULL_DATADIR="@CASAVA_FULL_DATADIR@" '
                           .'CASAVA_FULL_BINDIR="@CASAVA_FULL_BINDIR@" '
                           .'CASAVA_FULL_LIBDIR="@CASAVA_FULL_LIBDIR@" '
                           .'CASAVA_FULL_LIBEXECDIR="@CASAVA_FULL_LIBEXECDIR@" '
                           .'CASAVA_FULL_PERL_LIBDIR="@CASAVA_FULL_PERL_LIBDIR@" '
                       ." $PARAMS{postRunCmd}", "postRunCmd", "--postRunCmd script", "ALL_DONE" );
}

if ( $CONF_PROJ{isWorkflow} == 1 ) {
    taskManagerTarget( %PARAMS, %CONF_APP, %CONF_PROJ );
}

unless ( scalar(@targets) == 1 && $targets[0] eq 'allClean' ) {
    updateRunConfValue( 'currentStatus', $CONF_APP{stateFinished} );
    updateRunConfValue( 'endTime', ( strftime $timeStampFormat, localtime ) );
}    # unless
