package org.broadinstitute.hellbender;

import com.github.lindenb.jbwa.jni.AlnRgn;
import com.github.lindenb.jbwa.jni.BwaIndex;
import com.github.lindenb.jbwa.jni.BwaMem;
import com.github.lindenb.jbwa.jni.ShortRead;
import org.broadinstitute.hellbender.utils.NativeUtils;
import org.broadinstitute.hellbender.utils.bwa.BWANativeLibrary;
import org.broadinstitute.hellbender.utils.test.BaseTest;
import org.testng.Assert;
import org.testng.SkipException;
import org.testng.annotations.Test;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class JBWAIntegrationTest extends BaseTest {

    private void skipJBWATestOnUnsupportedPlatforms() {
        if ( ! NativeUtils.runningOnLinux() && ! NativeUtils.runningOnMac() ) {
            throw new SkipException("jbwa not available on this platform");
        }
        if ( NativeUtils.runningOnPPCArchitecture() ) {
            throw new SkipException("jbwa not available for this architecture");
        }
    }

    @Test
    public void testJBWAIsLoadable(){
        skipJBWATestOnUnsupportedPlatforms();

        BWANativeLibrary.load();
    }


    @Test
    public void testJBWAAlignSingleRead() throws Exception {
        skipJBWATestOnUnsupportedPlatforms();

        BWANativeLibrary.load();

        final BwaIndex index= new BwaIndex(new File(b37_reference_20_21));
        final BwaMem bwaMem = new BwaMem(index);
        try {
            //real read taken from src/test/resources/large/CEUTrio.HiSeq.WGS.b37.NA12878.20.21.bam
            final String name = "20FUKAAXX100202:3:46:9213:168594";
            final byte[] seqs = "GTTTTGTTTACTACAGCTTTGTAGTAAATTTTGAACTCTAAAGTGTTAGTTCTCTAACTTTGTTTGTTTTTCAAGAGTGTTTTGACTCTTCTTACTGCATC".getBytes();
            final byte[] quals = "DGFDGFDHFFFFGFEFHEGFFFGGHEHFHGHHGEGGGGGFGFHGHGHEHGGGFGAEFGDACAHHDHGCGFGGGFGDHGHFFHDDCGGDGEE".getBytes();
            final ShortRead read = new ShortRead(name, seqs, quals);
            final AlnRgn[] align = bwaMem.align(read);
            Assert.assertEquals(align.length, 1);
            Assert.assertEquals(align[0].getChrom(), "20");
            Assert.assertEquals(align[0].getCigar(), "101M");
            Assert.assertEquals(align[0].getMQual(), 60);
            Assert.assertEquals(align[0].getPos(), 9999997 - 1); // note difference from the bam file (9999997 in bam, 9999996 here)
            Assert.assertEquals(align[0].getNm(), 0);
        } finally {
            bwaMem.dispose();
            index.close();
        }
    }

    @Test
    public void testJBWAAlignChimericContig() throws Exception {
        skipJBWATestOnUnsupportedPlatforms();

        BWANativeLibrary.load();

        final BwaIndex index = new BwaIndex(new File(b37_reference_20_21));
        final BwaMem bwaMem = new BwaMem(index);

        try {
            final String name = "TestAssembledContig";
            // synthetic contig generated by extracting 300 bases from two different positions on chr20 in the reference
            final byte[] seqs = "GTGGGAGAGAACTGGAACAAGAACCCAGTGCTCTTTCTGCTCTACCCACTGACCCATCCTCTCACGCATCATACACCCATACTCCCATCCACCCACCTTCCCATTCATGCATTCACCCATTCACCCACCTTCCATCCATCTACCATCCACCACGTACCTACACTCCCATCTACCATCCAACCACATTTCCATTCACCCATCCTCCCATCCATCAACCCTCCAATCCACCACCCACAGACCTTCCCATCCATTCATTTACCCATCCACATATTCACCCACCCTCCCATCCATCCATCTACTTGAAGCAGAATGAGGGAGGAAACCCAAGCCAGCTCGGGCTTGATCATGGCAGGCTTTGTCAGTCACTGTGAGTAACCAGACTTTATTTCAAGTGAGTTGGCCAACAGTGTCTCCCCAGTAGTAGAGTGATTGCTCGTCTGCCAGAAAAGGGGCACAGAGCTCTGGACATCAATACTTGCCGATCTCTCCTTCATCAGCCACCCAACCCTGGCAACAGTTTTCAATTACACCTGTGAAAACTTGTGGGTTAAACAGCTGAGATCCATGCCTCAGCTTCTATAGGTGATAAGCCTGTCCTTC".getBytes();
            final byte[] quals = new byte[seqs.length];
            for (int i = 0; i < quals.length; i++) {
                quals[i] = 'A';
            }
            final ShortRead read = new ShortRead(name, seqs, quals);
            final AlnRgn[] align = bwaMem.align(read);

            Assert.assertEquals(align.length, 2);

            Arrays.sort(align, (o1, o2) -> new Long(o1.getPos()).compareTo(o2.getPos()));

            final AlnRgn alignRgn1 = align[0];
            Assert.assertEquals(alignRgn1.getChrom(), "20");
            Assert.assertEquals(alignRgn1.getCigar(), "300M300S");
            Assert.assertEquals(alignRgn1.getMQual(), 60);
            Assert.assertEquals(alignRgn1.getPos(), 999999);

            final AlnRgn alignRgn2 = align[1];
            Assert.assertEquals(alignRgn2.getChrom(), "20");
            Assert.assertEquals(alignRgn2.getCigar(), "300S300M");
            Assert.assertEquals(alignRgn2.getMQual(), 60);
            Assert.assertEquals(alignRgn2.getPos(), 1000999);
        } finally {
            bwaMem.dispose();
            index.close();
        }
    }

}

@@ -214,64 +214,8 @@
 ad;%0A
-import org.broadinstitute.hellbender.utils.NativeUtils;%0A
 impo
@@ -275,16 +275,16 @@
 ibrary;%0A
+
 import o
@@ -363,41 +363,8 @@
 rt;%0A
-import org.testng.SkipException;%0A
 impo
@@ -445,60 +445,8 @@
 ays;
-%0Aimport java.util.Comparator;%0Aimport java.util.List;
 %0A%0Apu
@@ -500,384 +500,8 @@
  %7B%0A%0A
-    private void skipJBWATestOnUnsupportedPlatforms() %7B%0A        if ( ! NativeUtils.runningOnLinux() && ! NativeUtils.runningOnMac() ) %7B%0A            throw new SkipException(%22jbwa not available on this platform%22);%0A        %7D%0A        if ( NativeUtils.runningOnPPCArchitecture() ) %7B%0A            throw new SkipException(%22jbwa not available for this architecture%22);%0A        %7D%0A    %7D%0A%0A
     
@@ -548,55 +548,8 @@
 ()%7B%0A
-        skipJBWATestOnUnsupportedPlatforms();%0A%0A
     
@@ -660,55 +660,8 @@
 n %7B%0A
-        skipJBWATestOnUnsupportedPlatforms();%0A%0A
     
@@ -1997,55 +1997,8 @@
 n %7B%0A
-        skipJBWATestOnUnsupportedPlatforms();%0A%0A
     
@@ -4096,12 +4096,14 @@
  %7D%0A    %7D
-%0A
+   
 %0A%7D%0A

fix jbwaIntegrationTest so it doesn't skip on ppc (#2118)