// Path: src/main/java/abra/ReadEvaluator.java
// static class Alignment {
// 	String chromosome;
// 	int pos;
// 	String cigar;
// 	Orientation orientation;
// 	int numMismatches;
// 		
// 	int contigPos;
// 	String contigCigar;
// 	boolean isSecondary;
// 		
// 	static final Alignment AMBIGUOUS = new Alignment();
// 		
// 	Alignment() {
// 	}
// 		
// 	Alignment(String chromosome, int pos, String cigar, Orientation orientation, int numMismatches, int contigPos, String contigCigar, boolean isSecondary) {
// 		this.chromosome = chromosome;
// 		this.pos = pos;
// 		this.cigar = cigar;
// 		this.orientation = orientation;
// 		this.numMismatches = numMismatches;
// 			
// 		this.contigPos = contigPos;
// 		this.contigCigar = contigCigar;
// 		this.isSecondary = isSecondary;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((cigar == null) ? 0 : cigar.hashCode());
// 		result = prime * result
// 				+ ((orientation == null) ? 0 : orientation.hashCode());
// 		result = prime * result + pos;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Alignment other = (Alignment) obj;
// 		if (cigar == null) {
// 			if (other.cigar != null)
// 				return false;
// 		} else if (!cigar.equals(other.cigar))
// 			return false;
// 		if (orientation != other.orientation)
// 			return false;
// 		if (pos != other.pos)
// 			return false;
// 		return true;
// 	}
// 
// }
// 
// Path: src/main/java/abra/ContigAligner.java
// public static class ContigAlignerResult {
// 		
// 	// Used for testing
// 	static boolean PAD_CONTIG = true;
// 		
// 	private int localRefPos;
// 	private String cigar;
// 		
// 	private String chromosome;
// 	private int refContextStart;
// 		
// 	private String sequence;
// 	private int score;
// 	private boolean isSecondary = false;
// 		
// 	public static final ContigAlignerResult INDEL_NEAR_END = new ContigAlignerResult();
// 
// 	private ContigAlignerResult() {
// 	}
// 		
// 	ContigAlignerResult(int refPos, String cigar, String chromosome, int refContextStart, String sequence, int score) {
// 		this.localRefPos = refPos;
// 		this.cigar = cigar;
// 		this.chromosome = chromosome;
// 		this.refContextStart = refContextStart;
// 		this.sequence = sequence;
// 		this.score = score;
// 	}
// 		
// 	public int getRefPos() {
// 		return localRefPos;
// 	}
// 	public String getCigar() {
// 		return cigar;
// 	}
// 
// 	public String getChromosome() {
// 		return chromosome;
// 	}
// 
// 	public int getRefContextStart() {
// 		return refContextStart;
// 	}
// 		
// 	// This is the actual genomic position 
// 	public int getGenomicPos() {
// 		return localRefPos + refContextStart;
// 	}
// 		
// 	public String getSequence() {
// 		return sequence;
// 	}
// 		
// 	public int getScore() {
// 		return score;
// 	}
// 		
// 	public boolean isSecondary() {
// 		return isSecondary;
// 	}
// 
// 	public void setSecondary(boolean isSecondary) {
// 		this.isSecondary = isSecondary;
// 	}
// }
// 
// Path: src/main/java/abra/SimpleMapper.java
// enum Orientation {
// 	UNSET, FORWARD, REVERSE;
// }


import java.util.HashMap;
import java.util.Map;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import abra.ReadEvaluator.Alignment;
import abra.ContigAligner.ContigAlignerResult;
import abra.SimpleMapper.Orientation;
package abra;





public class ReadEvaluatorTest {
	
	private Map<Feature, Map<SimpleMapper, ContigAlignerResult>> regionContigs;
	private Map<SimpleMapper, ContigAlignerResult> mappedContigs;
	
	@BeforeMethod ()
	public void setUp() {
		mappedContigs = new HashMap<SimpleMapper, ContigAlignerResult>();
		regionContigs = new HashMap<Feature, Map<SimpleMapper, ContigAlignerResult>>();
		regionContigs.put(new Feature("foo", 1, 1000), mappedContigs);
	}

	@Test (groups="unit")
	public void testSingleAlignmentSingleContig() {
		String contig1 = "ATCGAAAAAATTTTTTCCCCCCGGGGGGATCGGCTAATCG";
		String read    =     "ATAAAATTTTTTCCCCCCGGGGGGATCG";  // matches contig at 0 based position 4 with 1 mismatch
		
		SimpleMapper sm1 = new SimpleMapper(contig1, .05);
		ContigAlignerResult swc1 = new ContigAlignerResult(10, "10M1D30M", "chr1", 0, contig1, (short) 1);
		
		mappedContigs.put(sm1, swc1);
		
		ReadEvaluator re = new ReadEvaluator(regionContigs);
		
		// 1 mismatch in alignment to contig versus edit distance 2 in original read
		// should result in an improved alignment
		Alignment alignment = re.getImprovedAlignment(2, read);
		assertEquals(alignment.pos, 14);  // Alignment pos = 10 + 4
		assertEquals(alignment.cigar, "6M1D22M");
		assertEquals(alignment.numMismatches, 1);
// Path: src/main/java/abra/ReadEvaluator.java
// static class Alignment {
// 	String chromosome;
// 	int pos;
// 	String cigar;
// 	Orientation orientation;
// 	int numMismatches;
// 		
// 	int contigPos;
// 	String contigCigar;
// 	boolean isSecondary;
// 		
// 	static final Alignment AMBIGUOUS = new Alignment();
// 		
// 	Alignment() {
// 	}
// 		
// 	Alignment(String chromosome, int pos, String cigar, Orientation orientation, int numMismatches, int contigPos, String contigCigar, boolean isSecondary) {
// 		this.chromosome = chromosome;
// 		this.pos = pos;
// 		this.cigar = cigar;
// 		this.orientation = orientation;
// 		this.numMismatches = numMismatches;
// 			
// 		this.contigPos = contigPos;
// 		this.contigCigar = contigCigar;
// 		this.isSecondary = isSecondary;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((cigar == null) ? 0 : cigar.hashCode());
// 		result = prime * result
// 				+ ((orientation == null) ? 0 : orientation.hashCode());
// 		result = prime * result + pos;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Alignment other = (Alignment) obj;
// 		if (cigar == null) {
// 			if (other.cigar != null)
// 				return false;
// 		} else if (!cigar.equals(other.cigar))
// 			return false;
// 		if (orientation != other.orientation)
// 			return false;
// 		if (pos != other.pos)
// 			return false;
// 		return true;
// 	}
// 
// }
// 
// Path: src/main/java/abra/ContigAligner.java
// public static class ContigAlignerResult {
// 		
// 	// Used for testing
// 	static boolean PAD_CONTIG = true;
// 		
// 	private int localRefPos;
// 	private String cigar;
// 		
// 	private String chromosome;
// 	private int refContextStart;
// 		
// 	private String sequence;
// 	private int score;
// 	private boolean isSecondary = false;
// 		
// 	public static final ContigAlignerResult INDEL_NEAR_END = new ContigAlignerResult();
// 
// 	private ContigAlignerResult() {
// 	}
// 		
// 	ContigAlignerResult(int refPos, String cigar, String chromosome, int refContextStart, String sequence, int score) {
// 		this.localRefPos = refPos;
// 		this.cigar = cigar;
// 		this.chromosome = chromosome;
// 		this.refContextStart = refContextStart;
// 		this.sequence = sequence;
// 		this.score = score;
// 	}
// 		
// 	public int getRefPos() {
// 		return localRefPos;
// 	}
// 	public String getCigar() {
// 		return cigar;
// 	}
// 
// 	public String getChromosome() {
// 		return chromosome;
// 	}
// 
// 	public int getRefContextStart() {
// 		return refContextStart;
// 	}
// 		
// 	// This is the actual genomic position 
// 	public int getGenomicPos() {
// 		return localRefPos + refContextStart;
// 	}
// 		
// 	public String getSequence() {
// 		return sequence;
// 	}
// 		
// 	public int getScore() {
// 		return score;
// 	}
// 		
// 	public boolean isSecondary() {
// 		return isSecondary;
// 	}
// 
// 	public void setSecondary(boolean isSecondary) {
// 		this.isSecondary = isSecondary;
// 	}
// }
// 
// Path: src/main/java/abra/SimpleMapper.java
// enum Orientation {
// 	UNSET, FORWARD, REVERSE;
// }


// Path: src/test/java/abra/ReadEvaluatorTest.java
import java.util.HashMap;
import java.util.Map;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import abra.ReadEvaluator.Alignment;
import abra.ContigAligner.ContigAlignerResult;
import abra.SimpleMapper.Orientation;

package abra;





public class ReadEvaluatorTest {
	
	private Map<Feature, Map<SimpleMapper, ContigAlignerResult>> regionContigs;
	private Map<SimpleMapper, ContigAlignerResult> mappedContigs;
	
	@BeforeMethod ()
	public void setUp() {
		mappedContigs = new HashMap<SimpleMapper, ContigAlignerResult>();
		regionContigs = new HashMap<Feature, Map<SimpleMapper, ContigAlignerResult>>();
		regionContigs.put(new Feature("foo", 1, 1000), mappedContigs);
	}

	@Test (groups="unit")
	public void testSingleAlignmentSingleContig() {
		String contig1 = "ATCGAAAAAATTTTTTCCCCCCGGGGGGATCGGCTAATCG";
		String read    =     "ATAAAATTTTTTCCCCCCGGGGGGATCG";  // matches contig at 0 based position 4 with 1 mismatch
		
		SimpleMapper sm1 = new SimpleMapper(contig1, .05);
		ContigAlignerResult swc1 = new ContigAlignerResult(10, "10M1D30M", "chr1", 0, contig1, (short) 1);
		
		mappedContigs.put(sm1, swc1);
		
		ReadEvaluator re = new ReadEvaluator(regionContigs);
		
		// 1 mismatch in alignment to contig versus edit distance 2 in original read
		// should result in an improved alignment
		Alignment alignment = re.getImprovedAlignment(2, read);
		assertEquals(alignment.pos, 14);  // Alignment pos = 10 + 4
		assertEquals(alignment.cigar, "6M1D22M");
		assertEquals(alignment.numMismatches, 1);
		assertEquals(alignment.orientation, Orientation.FORWARD);