#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;

# This code is part of the MOCAT analysis pipeline
# Code is (c) Copyright EMBL and BGI, 2012-2013
# This code is released under GNU GPL v3.

my ( $insert, $format, @db, $read, %position, $step, $ids );
my $total = 0;
my $keep  = 0;

print STDERR "MOCATFilter_remove_in_padded.pl: STARTING.\n";

GetOptions(
	'format:s' => \$format,
	'db:s{,}'  => \@db,
	'step:s'   => \$step,
	'ids:s'    => \$ids
);

if (!(defined $format) || $format ne 'SAM' && $format ne 'SOAP') {
    $format = "NOT DEFINED" unless (defined $format);
    killme("Format is a mandatory option and must be one of SAM or SOAP (was $format).");
}

if ( $step eq 'screen' ) {
	open IDS, ">$ids";
}

sub killme {
	my $err = $_[0];
	my $gip  = getpgrp();
	print STDERR "ERROR & EXIT: $err\n";
	kill -9, $gip;
}

# Load hash
foreach my $file (@db) {
	open POS, "<$file.coord" or killme ("Cannot read $file.coord");
	while (<POS>) {
		chomp;
		my @line = split /\s+/;
        $position{$line[0]} = [] unless (exists $position{$line[0]});
		push @{$position{$line[0]}}, $line[1], $line[2];
	}
}

# Process STDIN
while (<STDIN>) {
	$total++;
	chomp( my $line = $_ );
	my @line = split "\t", $_;
	my $ref_id;
	my $first_base;
	my $length;
	my $last_base;
	my $direction;

	if ( $format eq 'SAM' ) {
        if ((scalar @line) < 10) {
            killme("Line $total does not seem to be in SAM format.\n");
        }
		$line[0] =~ m/(.+)\/([12])$/;
		$read       = $line[0];
		$insert     = $1;
		$direction  = $2;
		$ref_id     = $line[2];
		$first_base = $line[3];
		$length     = length $line[9];
		$last_base  = $first_base + $length - 1;
	}
	elsif ( $format eq 'SOAP' ) {
		$line[0] =~ m/(.+)\/([12])$/;
		$read       = $line[0];
		$insert     = $1;
		$direction  = $2;
		$ref_id     = $line[7];
		$first_base = $line[8];
		$length     = $line[5];
		$last_base  = $first_base + $length - 1;
	}

    my $bounds = $position{$ref_id};
    (defined $bounds) or
        killme("$ref_id was not found in len file.\n");

    my $n = 0;
    while ($n < scalar @{$bounds}) {
        my $lowb = $bounds->[$n];
        my $upb = $bounds->[$n+1];
        $n += 2;
        # Here the read matches, and then we remove both that read and its mate
        if ( !( $last_base < $lowb || $first_base > $upb ) ) {
            $keep++;
            if ( $step eq 'screen' ) {
                print IDS "$insert/1\n";
                print IDS "$insert/2\n";
            }
            print STDOUT "$line\n";
        }
        else {
            #print STDOUT "$line\n";
        }
    }
}

if ( $step eq 'screen' ) {
	close IDS;
}

print STDERR "Total number of reads:      $total\n";
print STDERR "Total number of reads kept: $keep\n";
print STDERR "MOCATFilter_remove_in_padded.pl: FINISHED.\n";

exit 0;
