package jp.ac.osaka_u.ist.sel.pret.engine.similarity;

import gnu.trove.TCharCollection;
import gnu.trove.iterator.TCharIterator;
import gnu.trove.map.TCharObjectMap;
import gnu.trove.map.hash.TCharObjectHashMap;

import java.io.Serializable;
import java.nio.file.*;
import java.util.Collection;

import jp.ac.osaka_u.ist.sel.pret.engine.data.FileInfo;
import jp.ac.osaka_u.ist.sel.pret.engine.data.ISimilarity;

public class CalcSim implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1262327329218392225L;
	private TCharObjectMap<WordReduce> words;
	private Path diffCommand = null;
	private int diffType;

	private static final int LCS_J = 0;
	private static final int DIFF_J = 1;
	private static final int DIFF_COM = 5;
	private static final int DIFF_CYG = 6;

	public CalcSim(TCharCollection types, int diffType, Path path) {
		words = new TCharObjectHashMap<>();
		for (TCharIterator it = types.iterator(); it.hasNext();) {
			words.put(it.next(), new WordReduce());
		}
		this.diffType = diffType;
		if (diffType >=5) {
			if (diffCommand != null && Files.isExecutable(diffCommand)) {
				this.diffCommand = path;
			} else {
				this.diffType = LCS_J;
			}
		}
	}

	public void calc(ISimilarity diffmap, Collection<FileInfo> addedFiles, Collection<FileInfo> files, float threshold) {
		for (FileInfo fi : addedFiles) {
			words.get(fi.type()).set(fi);
		}

		ASim calc = sim(diffmap, files, threshold);
		calc.calc(addedFiles);
	}

	public void calcAll(ISimilarity diffmap, Collection<FileInfo> files, float threshold) {
		ASim calc = sim(diffmap, files, threshold);
		calc.calcAll();
	}

	private ASim sim(ISimilarity diffmap, Collection<FileInfo> files, float threshold) {
		switch (diffType) {
		case DIFF_COM:
			return new SimCommandDiffWR(diffmap, files, diffCommand.toString(), words, threshold);
		case DIFF_CYG:
			return new SimCygwinDiffWR(diffmap, files, diffCommand.toString(), words, threshold);
		case DIFF_J:
			return new SimTKJavaDiffWR(diffmap, files, words, threshold);
		case LCS_J:
		default:
			return new SimNKLCSWR(diffmap, files, words, threshold);

		}
	}
}
