package cn.edu.seu.ise.dca.analysis;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import cn.edu.seu.ise.dca.filter.RevisionFilter;
import cn.edu.seu.ise.dca.model.Revision;
import cn.edu.seu.ise.dca.util.ExcelWriter;

public class SVNAnalyzer {
	
	static Logger logger = Logger.getLogger(SVNAnalyzer.class);
	
	private List<Revision> revisions;
	private List<String> includedUrls;
	private List<String> excludedUrls;
	
	public SVNAnalyzer(List<Revision> revisions) {
		this.revisions = revisions;
		this.includedUrls = new ArrayList<String>();
		this.excludedUrls = new ArrayList<String>();
	}
	
	public SVNAnalyzer(List<Revision> revisions, List<String> includedUrls, List<String> excludedUrls) {
		this(revisions);
		if(includedUrls != null) {
			this.includedUrls = includedUrls;
		}
		if(excludedUrls != null) {
			this.excludedUrls = excludedUrls;
		}
	}

	/**
	 * @return the number of all revision in consideration
	 */
	public long sizeOfRevisions() {
		return this.revisions.size();
	}
	
	public void generateReport(String filePath) {
		ExcelWriter writer = new ExcelWriter(filePath);
		//Set the first line
		writer.addCaption(0, 0, "revision");
		writer.addCaption(1, 0, "Files(C)");
		writer.addCaption(2, 0, "Files(CC)");
		writer.addCaption(3, 0, "Files(AC)");
		writer.addCaption(4, 0, "Files(DC)");
		writer.addCaption(5, 0, "Files(MC)");
	
		writer.addCaption(6, 0, "Class(T)");
		writer.addCaption(7, 0, "Class(C)");
		writer.addCaption(8, 0, "Class(CC)");
		writer.addCaption(9, 0, "Class(AC)");
		writer.addCaption(10, 0, "Class(DC)");
		writer.addCaption(11, 0, "Class(MC)");
		
		writer.addCaption(12, 0, "GFunc(T)");
		writer.addCaption(13, 0, "GFunc(C)");
		writer.addCaption(14, 0, "GFunc(CC)");
		writer.addCaption(15, 0, "GFunc(AC)");
		writer.addCaption(16, 0, "GFunc(DC)");
		writer.addCaption(17, 0, "GFunc(MC)");
		
		writer.addCaption(18, 0, "MFunc(T)");
		writer.addCaption(19, 0, "MFunc(C)");
		writer.addCaption(20, 0, "MFunc(CC)");
		writer.addCaption(21, 0, "MFunc(AC)");
		writer.addCaption(22, 0, "MFunc(DC)");
		writer.addCaption(23, 0, "MFunc(MC)");
		
		writer.addCaption(24, 0, "Line(TO)");
		writer.addCaption(25, 0, "Line(TR)");
		writer.addCaption(26, 0, "Line(CO)");
		writer.addCaption(27, 0, "Line(CR)");
		writer.addCaption(28, 0, "Line(CCO)");
		writer.addCaption(29, 0, "Line(CCR)");
		writer.addCaption(30, 0, "Line(AC)");
		writer.addCaption(31, 0, "Line(DC)");
		writer.addCaption(32, 0, "Line(MCO)");
		writer.addCaption(33, 0, "Line(MCR)");
		
		writer.addCaption(34, 0, "Line(TO[A])");
		writer.addCaption(35, 0, "Line(TR[A])");
		writer.addCaption(36, 0, "Line(CO[A])");
		writer.addCaption(37, 0, "Line(CR[A])");
		writer.addCaption(38, 0, "Line(CCO[A])");
		writer.addCaption(39, 0, "Line(CCR[A])");
		writer.addCaption(40, 0, "Line(AC[A])");
		writer.addCaption(41, 0, "Line(DC[A])");
		writer.addCaption(42, 0, "Line(MCO[A])");
		writer.addCaption(43, 0, "Line(MCR[A])");
		
		RevisionFilter RFilter = new RevisionFilter(this.includedUrls, this.excludedUrls);
		for(int i = 0; i < revisions.size(); i++) {
			int row = i + 1;
			Revision revision = revisions.get(i);
			Revision filterRivision = RFilter.filter(revision);
			
			logger.info("Calculate the statiscal result of revision " + revision.getId());
			
			writer.addNumber(0,  row, revision.getId());
			writer.addNumber(1,  row, revision.sizeOfChangedFiles());
			writer.addNumber(2,  row, filterRivision.sizeOfChangedFiles());
			writer.addNumber(3,  row, filterRivision.sizeOfAddedFiles());
			writer.addNumber(4,  row, filterRivision.sizeOfDeletedFiles());
			writer.addNumber(5,  row, filterRivision.sizeOfModifiedFiles());
			
			writer.addNumber(6,  row, revision.sizeOfClasses());
			writer.addNumber(7,  row, filterRivision.sizeOfClasses());
			writer.addNumber(8,  row, filterRivision.sizeOfChangedClasses());
			writer.addNumber(9,  row, filterRivision.sizeOfAddedClasses());
			writer.addNumber(10, row, filterRivision.sizeOfDeletedClasses());
			writer.addNumber(11, row, filterRivision.sizeOfModifiedClasses());
			
			writer.addNumber(12, row, revision.sizeOfGlobalFunctions());
			writer.addNumber(13, row, filterRivision.sizeOfGlobalFunctions());
			writer.addNumber(14, row, filterRivision.sizeOfChangedGlobalFunctions());
			writer.addNumber(15, row, filterRivision.sizeOfAddedGlobalFunctions());
			writer.addNumber(16, row, filterRivision.sizeOfDeletedGlobalFunctions());
			writer.addNumber(17, row, filterRivision.sizeOfModifiedGlobalFunctions());
			
			writer.addNumber(18, row, revision.sizeOfMemberFunctions());
			writer.addNumber(19, row, filterRivision.sizeOfMemberFunctions());
			writer.addNumber(20, row, filterRivision.sizeOfChangedMemberFunctions());
			writer.addNumber(21, row, filterRivision.sizeOfAddedMemberFunctions());
			writer.addNumber(22, row, filterRivision.sizeOfDeletedMemberFunctions());
			writer.addNumber(23, row, filterRivision.sizeOfModifiedMemberFunctions());
			
			writer.addNumber(24, row, revision.sizeOfLines(false));
			writer.addNumber(25, row, revision.sizeOfLines(true));
			writer.addNumber(26, row, filterRivision.sizeOfLines(false));
			writer.addNumber(27, row, filterRivision.sizeOfLines(true));
			writer.addNumber(28, row, filterRivision.sizeOfChangedLines(false, false));
			writer.addNumber(29, row, filterRivision.sizeOfChangedLines(true, false));
			writer.addNumber(30, row, filterRivision.sizeOfAddedLines(false));
			writer.addNumber(31, row, filterRivision.sizeOfDeletedLines(false));
			writer.addNumber(32, row, filterRivision.sizeOfModifiedLines(false, false));
			writer.addNumber(33, row, filterRivision.sizeOfModifiedLines(true, false));
			
			
			writer.addNumber(34,  row, revision.sizeOfActLines(false));
			writer.addNumber(35,  row, revision.sizeOfActLines(true));
			writer.addNumber(36,  row, filterRivision.sizeOfActLines(false));
			writer.addNumber(37,  row, filterRivision.sizeOfActLines(true));
			
			writer.addNumber(38, row, filterRivision.sizeOfChangedLines(false, true));
			writer.addNumber(39, row, filterRivision.sizeOfChangedLines(true, true));
			writer.addNumber(40, row, filterRivision.sizeOfAddedLines(true));
			writer.addNumber(41, row, filterRivision.sizeOfDeletedLines(true));
			writer.addNumber(42, row, filterRivision.sizeOfModifiedLines(false, true));
			writer.addNumber(43, row, filterRivision.sizeOfModifiedLines(true, true));
			
		}
		writer.close();
	}
	

}
