#!/usr/bin/env perl
# PROJECT: CASAVA
# MODULE:  $RCSfile: mergeRealignedBam.pl,v $
# AUTHER: Chris Saunders
#
# Copyright (c) 2006 Solexa, 2007,2008 Illumina
# 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).
#

use warnings FATAL => 'all';
use strict;

use File::Copy qw(move);
use File::Spec;
use IO::File;
use Sys::Hostname;
use Getopt::Long;

use lib '@CASAVA_FULL_PERL_LIBDIR@';
use Casava::Common::Log;
use Casava::Common::IOLib qw(createDir executeCmd);
use Casava::PostAlignment::Sequencing::Config qw(loadConfiguration %CONF_APP %CONF_PROJ %chrEnds readProjectParameters);
use Casava::PostAlignment::Sequencing::SamLib qw(getSamtoolsBin);

my $argvStr     = join(' ', @ARGV);
my $cmdline     = "$0 $argvStr";
my $scriptName = (File::Spec->splitpath($0))[2];

my $projectDir        = "";
my $chrom             = "";
my $sampleRateSetSuffix = '';
my $help              = 0;

my $usage       =<<END;
$scriptName [options]
\t--projectDir   - project directory
\t--chrom        - chromosome
\t-h|--help      - print this message
END


my $result            = GetOptions(
    "projectDir=s" => \$projectDir,
    "chrom=s"      => \$chrom,
    "help|h"       => \$help
);

if ((not $result)  or $help) {
    errorExit "\n\n$usage";
}

errorExit "ERROR: Incorrect number of arguments\n$usage" unless ( $projectDir ne "" );

if(@ARGV) {
    errorExit "ERROR: Unrecognized arguments: " . join(' ',@ARGV) . "\n";
}

{
    my $hostname = hostname();
    printLog( "Running $hostname:[$cmdline]\n", 0);
}

loadConfiguration($projectDir);

if(not defined $chrEnds{$chrom}){
    errorExit "ERROR: Invalid chromosome label: $chrom\n";
}

my $confDir         = $CONF_APP{dirConf};
my $confFile        = $CONF_APP{projectConf};
my $bamDirName      = $CONF_APP{dirBam};
my $dirCurrentBuild = $CONF_PROJ{dirBuildParsed};
my $samtoolsBin      = getSamtoolsBin(%CONF_PROJ);

my %buildChromsBinSizes = ();
readProjectParameters( %buildChromsBinSizes, "BUILD_BIN_SIZES",$projectDir);
my $binCount=$buildChromsBinSizes{$chrom};

my $chromDir = File::Spec->catdir($dirCurrentBuild, $chrom);
errorExit "ERROR: Can't find chromosome directory: $chromDir\n" unless (-d $chromDir);

my $bam_f = "sorted.realigned.bam";

my @binBams = ();
for(my $i=0;$i<$binCount;++$i) {
    my $binId = sprintf "%04d", $i;

    my $binDir = File::Spec->catdir($chromDir, $binId);
    if (not -d $binDir) {
        logWarning("No bin dir $binDir for chr $chrom - skipping");
        next;
    }

    my $binBamPath = File::Spec->catfile($binDir, $bam_f);
    if (not -f $binBamPath) {
        logWarning("No ${bam_f} under $binDir - skipping");
        next;
    }

    push(@binBams, $binBamPath);
}

if (not @binBams) {
   logWarning("No non-empty bins for chr $chrom - skipping");
   exit;
}


# merge bin bam files:
#
my $realignedDirName="realigned";
my $realignedDirPath=File::Spec->catdir( $chromDir, $bamDirName, $realignedDirName );

createDir($realignedDirPath) if(not -e $realignedDirPath);
errorExit "ERROR: can't create dir: $realignedDirPath\n" if(not -d $realignedDirPath);

my $chromBamPath = File::Spec->catfile($realignedDirPath, $bam_f);
my $tmpChromBamPath = "$chromBamPath.incomplete";

if((scalar @binBams) == 0){
    errorExit "ERROR: No bin BAM files to be merged.\n";
} elsif((scalar @binBams) == 1){
    move($binBams[0],$chromBamPath) or errorExit("ERROR: File move failed: $!\n");
} else {
    my $chromBamMergeCmd = "$samtoolsBin merge $tmpChromBamPath ";
    $chromBamMergeCmd .= join(' ',@binBams);
    executeCmd($chromBamMergeCmd,0);
    move($tmpChromBamPath,$chromBamPath) or errorExit("ERROR: File move failed: $!\n");

    my $cnt = unlink @binBams;
    errorExit "Failed to remove bin BAM files from list: @binBams\n" unless ($cnt == scalar(@binBams));
}

my $chromBamIndexCmd = "$samtoolsBin index $chromBamPath";
executeCmd($chromBamIndexCmd,0);





