/*
 * Copyright (C) 1999-2007 <a href="mailto:paschke@in.tum.de">Adrian Paschke</a>
 * 
 * The Regression Test framework is part of the Rule Based Service Level Agreement (RBSLA)
 * project, available at 
 * <a href=" http://ibis.in.tum.de/staff/paschke/rbsla/index.htm">RBSLA</a>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package rbsla.regressiontest;

import rbsla.wrapper.ProvaWrapper;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.*;

import org.mandarax.kernel.ResultSet;
import org.mandarax.kernel.Term;
import ws.prova.RListUtils;



/**
 * Test coverage for a automatic coverage measurment of the RBSLA/ConractLog test cases.
 * The system is able to automaticly measure the test coverage and create a test coverage report.
 * 
 * It currently also builds the html output, but it is planned to generalize this and adapt an existing
 * test cover tool to build test coverage reports for logic programs.
 * 
 * @author <A HREF="mailto:paschke@in.tum.de">Adrian Paschke</A>
 * @version 0.1 <1 December 2005>
 * @since 0.1
 */
public class RegressionTestCoverage
{
	
	
	public RegressionTestCoverage() {
		
	}
	
	private String html_header() {
		String head = new String(""+
		
				"<html>"+
				"<head>"+
				"<META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">"+
				"<title>ContractLog Test Coverage</title>"+
				"<style type=\"text/css\">"+
				      "body {"+
				        "font:normal 68% verdana,arial,helvetica;"+
				        "color:#000000;"+
				      "}"+
				      "table tr td, tr th {"+
				          "font-size: 68%;"+
				      "}"+
				      "table.details tr th{"+
				        "font-weight: bold;"+
				        "text-align:left;"+
				        "background:#a6caf0;"+
				      "}"+
				      "table.details tr td{"+
				        "background:#eeeee0;"+
				      "}"+
				      
				      "p {"+
				        "line-height:1.5em;"+
				        "margin-top:0.5em; margin-bottom:1.0em;"+
				        "margin-left:2em;"+
				        "margin-right:2em;"+
				      "}"+
				      "h1 {"+
				        "margin: 0px 0px 5px; font: 165% verdana,arial,helvetica"+
				      "}"+
				      "h2 {"+
				        "margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica"+
				      "}"+
				      "h3 {"+
				        "margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica"+
				      "}"+
				      "h4 {"+
				        "margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica"+
				      "}"+
				      "h5 {"+
				        "margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica"+
				      "}"+
				      "h6 {"+
				        "margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica"+
				      "}"+
				      ".Error {"+
				        "font-weight:bold; color:red;"+
				      "}"+
				      ".Failure {"+
				        "font-weight:bold; color:purple;"+
				      "}"+
				      ".Properties {"+
				        "text-align:right;"+
				      "}"+
				      "</style>"+
				"</head>"+
				"<body>"+
				"<h1>"+
				"<a name=\"top\">ContractLog Analysis</a>"+
				"</h1>"+
				"<p align=\"right\">Designed for use with <a href=\"http://ibis.in.tum.de/staff/paschke/rbsla/contractlog.htm\">ContractLog LPCover</a> and <a href=\"http://jakarta.apache.org\">Ant</a>.</p>"+
				"<hr size=\"2\">"+
				"<table width=\"100%\">"+
				"<tr>"+
				"<td><a name=\"NVsummary\">"+
				"<h2>Summary</h2>"+
				"</a></td><td align=\"right\">"+
				   
				    "</td>"+
				"</tr>"+
				"</table>");
		
		return head;
	}
	
	private String html_footer() {
		String body = new String(
				"</body>"+
				"</html>"
		);
		return body;
	}
	
	private String buildReport(List report) {
		
		String rep = new String(""+
				"<table width=\"100%\" class=\"details\">"+
					"<tr>"+
						"<th>Test Case</th><th>Overall Clauses</th><th><a href=\"#Cov\">Covered Clauses</a></th><th><a href=\"#NotCov\">Not Covered Clauses</a></th><th><a href=\"#CoverageLevel\">CoverageLevel</a></th>"+
					"</tr>"
		);
		
		for (Iterator it = report.iterator();it.hasNext();) {
			List entry = (List) it.next();			
			String testcase = (String) entry.get(0);
			Object lp = entry.get(1);
			Object coveredClauses = entry.get(2);
			Object notCoveredClauses = entry.get(3);
			Object overall = entry.get(4);
			Object notcovered = entry.get(5);
			Object covered = entry.get(6);
			Object coverage = entry.get(7);
			rep=rep+buildCoverageEntry((Object)testcase,overall,covered,notcovered,coverage);
		}
			
		rep = rep +"<table>\r\n";
	
		
		for (Iterator it2 = report.iterator();it2.hasNext();) {
			List entry = (List) it2.next();
			String testcase = (String) entry.get(0);
			Object coveredClauses = entry.get(2);
			Object notCoveredClauses = entry.get(3);

			rep=rep+"<table width=\"100%\" class=\""+testcase+"\">"+
			"<tr>"+
				"<td><a name=\""+testcase+"\"><H3>"+testcase+"</H3></a></td>"+
		    "</tr>"+	
			"<tr>"+
				"<td><b>Covered Clauses</b></td>"+
			"</tr>"+	
			"<tr>"+
				"<td>"+coveredClauses+"</td>"+
			"</tr>"+
			"<tr>"+
				"<td><b>Not Covered Clauses</b></td>"+
			"</tr>"+
			"<tr>"+
				"<td>"+notCoveredClauses+"</td>"+
			"</tr>"+	
			"</table>";
		}
		
		return rep;
	}
	
	private String buildCoverageEntry(Object name, Object oa, Object co, Object nc, Object level) {
		String entry = new String("<tr>");
		entry = entry + 
		"<td align=\"left\"><a href=\"#"+name+"\">"+name+"</a></td><td align=\"right\">"+oa+"</td><td align=\"right\">"+co+"</td><td align=\"right\">"+nc+"</td><td align=\"right\">"+level+"</td>";	
		entry = entry+"<tr>";
		return entry;
	}
	
    /**
     * Compute the test coverage for the tests
     * @return List the collected results of the coverage measurement as a lists
     */
    public List computeCoverage() {		
        ProvaWrapper wrapper = new ProvaWrapper("./examples/test_cases/coverage.prova");		
		List testCases = wrapper.solveVar("test(TestCase)","TestCase");
		wrapper.consult("consult(\"./examples/test_cases/coverage.prova\").");
		ArrayList report = new ArrayList();
        for(int i = 0; i < testCases.size(); i++) {
            try {
								
				ArrayList reportEntry = new ArrayList();
				String testCase = testCases.get(i).toString();
				wrapper.consult("consult(\""+testCase+"\").");
				reportEntry.add(testCase);
				ResultSet rs = wrapper.consult("testCoverage(LP,CoveredClauses,NotCoveredClauses,OverAll,NotCovered,Covered,CoverageLevel)");
				boolean more = rs.first();
				while (more) {
					Object lp = rs.getResult(Object.class, "LP"); 			
					Object coveredClauses = rs.getResult(Object.class, "CoveredClauses");
					Object notCoveredClauses = rs.getResult(Object.class, "NotCoveredClauses");
					Object overall = rs.getResult(Object.class, "OverAll");
					Object notcovered = rs.getResult(Object.class, "NotCovered");
					Object covered= rs.getResult(Object.class, "Covered");
					Object coverage= rs.getResult(Object.class, "CoverageLevel");
					
					reportEntry.add(lp);
					reportEntry.add(coveredClauses);
					reportEntry.add(notCoveredClauses);
					reportEntry.add(overall);
					reportEntry.add(notcovered);
					reportEntry.add(covered);
					reportEntry.add(coverage);
					
					report.add(reportEntry);
					
					more = rs.next();					
			   }
				
			   wrapper.consult("unconsult(\""+testCase+"\").");
				
            } catch(Exception x) {
                System.err.println ("Cannot find coverage file!");
                x.printStackTrace (System.err);
            }
        }			
        return report;
    }
	
	public String creatReport() {
		String report = html_header()+buildReport(computeCoverage())+html_footer();
		return report;
	}
	
	private void write(String report) {
	  try {	
		BufferedWriter out = new BufferedWriter(
				new OutputStreamWriter(
						new FileOutputStream("target/LPCover.html")
				)
		);
		
		out.write(report);
		
		out.close();
	  } catch (Exception e) {System.err.println(e);}	
	  return;
	}
	
	public static void main(String[] argv)   {
		RegressionTestCoverage rtc = new RegressionTestCoverage();
		rtc.write(rtc.creatReport());
		System.exit(0);
	}

}