/* Copyright (c) 2012,
 * Mathias Kuhring, KuhringM@rki.de, Robert Koch-Institut, Germany, 
 * All rights reserved. For details, please note the license.txt.
 */

package de.rki.ng4.ipig.mapping;

import java.util.HashMap;
import java.util.Vector;

import de.rki.ng4.ipig.data.Gene;
import de.rki.ng4.ipig.data.GeneSet;
import de.rki.ng4.ipig.data.Peptide;
import de.rki.ng4.ipig.data.PeptideSet;
import de.rki.ng4.ipig.exceptions.ExitException;
import de.rki.ng4.ipig.tools.Configurator;
import de.rki.ng4.ipig.tools.Info;
import de.rki.ng4.ipig.tools.Logger;
import de.rki.ng4.ipig.tools.Translator;

/**
 * <p>This class can validate the position results. It's more for development testing than for end user usage,
 * cause it needs a GeneSet with nucleotide sequence data, which needs a lot of memory.</p>
 * 
 * @author Mathias Kuhring
 */
public class Validator {

	/**
	 * For all Peptides the validation takes Genes nucleotide sequences and extracts the parts indicated by the Peptide's positions.
	 * The parts are then translated to amino acid sequences and compared with the Peptide's sequence.
	 * 
	 * @param peps
	 * @param genes
	 * @throws ExitException
	 */
	public static void validate(PeptideSet peps, GeneSet genes) throws ExitException{
		Info info = new Info("validate mappings");
		int count = 0;

		HashMap<String, Vector<Integer>> genemap = peps.getCommonGenes();
		Vector<Integer> pepidx;
		Peptide pep;
		Gene gene;
		String dna;
		String peptide;
		Translator trans = new Translator();
		boolean match;
		StringBuffer output = new StringBuffer();

		for (int g=0; g<genes.size(); g++){
			gene = genes.get(g);
			pepidx = genemap.get(genes.get(g).getName());
			if (pepidx != null){
				for (int i=0; i<pepidx.size(); i++){
					pep = peps.get(pepidx.get(i));

					for (Position pos : pep.getPositions()){
						if (pos.getGeneName().matches(gene.getName()) && !pos.isValidated()){

							dna = getDna(pos,gene);
							peptide = trans.dnaToPeptide(dna).split("\\*")[0]; 
							match = pep.getSequence().equals(peptide);
							if (!match){
								String message = "wrong mapping: " + peptide + "<>" + pep.getSequence() + "\t" + 
										pep.getMatchMethod() + "\t" + pos.getGeneName() + "\t" + pos.getChrom() + "\t" + pos.getStrand() 
										+ "\t" +  pos.getStartPos() + "\t" + pos.getEndPos();
								Logger.write(Configurator.getSysProperty("msPepSetName", "ipig")+".log", message);
								output.append(message + "\n");
							}
							pos.setValidated(true);
							count++;
						}
					}
				}
				Configurator.checkBreak();
			}
		}

		info.stop(count, peps.mapPosCount());
		System.out.print(output.toString());
	}

	// Extracts a part of a Gene's dna sequence indicated by a Position
	private static String getDna(Position pos, Gene gene){
		Vector<Integer> starts = pos.getStartPos();
		Vector<Integer> ends = pos.getEndPos();
		StringBuffer dna = new StringBuffer();

		int start;
		int end;

		for (int i=0; i<starts.size(); i++){
			start = starts.get(i) - gene.getTxStart();
			end = ends.get(i) - gene.getTxStart();
			dna.append(gene.getSequence().substring(start, end));
		}

		if (gene.getStrand() == '-'){
			dna.reverse();
			return Translator.complement(dna.toString());
		}
		else{
			return dna.toString().toUpperCase();
		}
	}
}
