package br.inpe.cap.evolution.processor;

import static br.inpe.cap.evolution.parser.XmlMavenParser.replaceLineFeedAndComma;

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Locale;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.repodriller.domain.Commit;
import org.repodriller.persistence.PersistenceMechanism;
import org.repodriller.scm.RepositoryFile;
import org.repodriller.scm.SCMRepository;

import br.inpe.cap.evolution.domain.MavenDependency;
import br.inpe.cap.evolution.domain.MavenProject;
import br.inpe.cap.evolution.maven.MavenEffectivePom;
import br.inpe.cap.evolution.maven.UnparsableEffectivePomException;
import br.inpe.cap.evolution.parser.XmlMavenParser;

public class EffectivePomSynchronousCheckoutProcessor extends SynchronousCheckOutRepositoryProcessor {
	
	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

	/**
	 * Formato da porcentagem com "." para não confundir com a "," do CSV
	 */
	private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.00000", DecimalFormatSymbols.getInstance(Locale.US));

	private final PersistenceMechanism writer;
	private final int totalCommits;
	private int currentHashPosition;
	private float percent;
	private final VersionEvolutionDetectorPostProcessor versionEvolutionDetector = new VersionEvolutionDetectorPostProcessor();
	private final MavenEffectivePom mavenEffectivePom = new MavenEffectivePom();
	private final XmlMavenParser parser = new XmlMavenParser();
	private final Logger logger;

	public EffectivePomSynchronousCheckoutProcessor(final CheckoutObserver observer, final PersistenceMechanism writer, final int totalCommits, final Logger logger) {
		super(observer);
		this.writer = writer;
		this.totalCommits = totalCommits;
		this.logger = logger;
	}

	@Override
	protected void processFile(final SCMRepository repo, final Commit commit, final RepositoryFile file) {
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		final MavenProject mavenProject = parser.readPOM(getEffectiveOrOriginalPom(file));
		mavenProject.getDependencies().forEach(
			(dependency) -> 
				versionEvolutionDetector.processLine(
					writer, this.obtainCsvLine(repo.getLastDir(), commit, this.currentHashPosition, this.totalCommits, this.percent, file.getFullName(), dependency))
			);
	}

	private String getEffectiveOrOriginalPom(final RepositoryFile file) {
		String effectivePom = "";
		try {
			effectivePom = mavenEffectivePom.resolveEffectivePom(file.getFile());
		} catch (final UnparsableEffectivePomException e) {
			logger.error("Effective POM from file " + file.getFullName()
						+ " could not be extracted. Proceeding with original POM. See result:\n"
						+ e.getMessage());
			effectivePom = getOriginalPom(file, effectivePom);
		}
		return effectivePom;
	}

	private String getOriginalPom(final RepositoryFile file, String effectivePom) {
		try {
			effectivePom = FileUtils.readFileToString(file.getFile());
		} catch (final IOException ioe) {
			logger.error("Error reading POM from file " + file.getFullName());
		}
		return effectivePom;
	}

	public void setCurrentHashPosition(final int currentHashPosition) {
		this.currentHashPosition = currentHashPosition;
	}
	
	public void setPercent(final float percent) {
		this.percent = percent;
	}

	private String obtainCsvLine(final String repositoryName, final Commit commit, final int currentHashPosition, final int totalCommits, final float percent, final String fileName, final MavenDependency mavenDependency) {
		final StringBuilder sb = new StringBuilder();
		sb.append(commit.getHash());								sb.append(",");
		sb.append(DATE_FORMAT.format(commit.getDate().getTime()));	sb.append(",");
		sb.append(repositoryName);									sb.append(",");
		sb.append(fileName);										sb.append(",");
		sb.append(currentHashPosition);								sb.append(",");
		sb.append(totalCommits);									sb.append(",");
		sb.append(PERCENT_FORMAT.format(percent));					sb.append(",");
		sb.append(mavenDependency.isDependencyManaged());			sb.append(",");
		sb.append(mavenDependency.getGroupId());					sb.append(",");
		sb.append(mavenDependency.getArtifactId());					sb.append(",");
		sb.append(mavenDependency.getVersion());					sb.append(",");
		sb.append(replaceLineFeedAndComma(commit.getMsg()));
		return sb.toString();
	}
	
}
@@ -286,16 +286,55 @@
 Locale;%0D
+%0Aimport java.util.concurrent.TimeUnit;%0D
 %0A%0D%0Aimpor
@@ -2135,16 +2135,14 @@
 %0D%0A%09%09
-Thread.c
+setupC
 urre
@@ -2154,41 +2154,45 @@
 ead(
-).setPriority(Thread.MIN_PRIORITY
+file.getFullName(), repo.getLastDir()
 );%0D%0A
@@ -2536,16 +2536,16 @@
 ency))%0D%0A
-
 %09%09%09);%0D%0A%09
@@ -2541,32 +2541,413 @@
 )%0D%0A%09%09%09);%0D%0A%09%7D%0D%0A%0D%0A
+%09private void setupCurrentThread(final String fileFullName, final String repositoryName) %7B%0D%0A%09%09try %7B%0D%0A%09%09%09final Thread currentThread = Thread.currentThread();%0D%0A%09%09%09currentThread.setName(fileFullName.substring(fileFullName.indexOf(repositoryName)));%0D%0A%09%09%09currentThread.setPriority(Thread.MIN_PRIORITY);%0D%0A%09%09%09Thread.sleep(TimeUnit.SECONDS.toMillis(2));%0D%0A%09%09%7D catch (Exception e) %7B%7D%0D%0A%09%7D%0D%0A%0D%0A
 %09private String 

Configura EffectivePomProcessor Thread para ser identificada no debug e tentativa de alivar CPU load com Thread.sleep de alguns segundos.