package de.uka.ipd.consensus.test;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import de.snailshell.consensus.demo.ConsensusFoundationUtils;
import de.uka.ipd.consensus.foundation.ConsensusFoundation;
import de.uka.ipd.consensus.foundation.logging.LoggingManager;
import de.uka.ipd.consensus.foundation.ontology.OntologyManager;
import de.uka.ipd.consensus.foundation.schema.Rating;
import de.uka.ipd.consensus.foundation.schema.Topic;
import de.uka.ipd.consensus.foundation.schema.User;
import de.uka.ipd.consensus.foundation.user.UserManager;

/**
 * <p>Warning: This rating test creates 1 topic, 100 users and 100 ratings,
 * so use it on a separate hibernate.connection.url (see hibernate.properties)
 * and with a different ResourceParams-url (see context.xml).
 * <p>Make sure that the servlet, its servlet-mapping and its filter-mapping are activated in web.xml.
 * <p>Note: The test deactivates logging for not measuring performance penalties due to slow console ouput.
 * @author Thomas Much
 * @version 2006-06-14
 */
public class RatingTestServlet extends HttpServlet {
	
	private static final String TESTUSERNAME_PREFIX = "__test_user_";
	private static final int    MAX_USERS           = 100;
	
	private volatile static int numRatings = 0;


	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/plain");
		
		PrintWriter out = res.getWriter();

		ConsensusFoundation cf = ConsensusFoundationUtils.getConsensusFoundationManager( this.getServletContext() );
		UserManager         um = cf.getUserManager();
		OntologyManager     om = cf.getOntologyManager();
		
		int oldlevel = cf.getLoggingManager().getLevel();
		
		cf.getLoggingManager().setLevel( LoggingManager.LEVEL_OFF );

		out.println( "Starting rating test, generating " + MAX_USERS + " users ..." );
		out.flush();

		try {
			this.generateUsers( um );
			
			User usr = um.getUserByUsername( TESTUSERNAME_PREFIX + "0" );

			Topic t = om.createTopic( usr, null, null, null);

			out.println( "#Ratings,read 1 rating,read all ratings" );
			out.flush();

			for (int i = 0; i <= 10; i++) {
				if (i == 0) {
					out.print( numRatings + "," );
					out.flush();
				}
				else {
					this.generate10Ratings( out, t, um );
				}
				
				this.read1Rating( out, t, um );
				this.readAllRatings( out, t );
				
				out.println();
				out.flush();
			}
		}
		catch (IOException e) {
			throw e;
		}
		catch (Exception e) {
			throw new ServletException( e );
		}
		
		out.println( "... done." );
		out.flush();
		
		cf.getLoggingManager().setLevel( oldlevel );
	}
	

	private void read1Rating(PrintWriter out, Topic t, UserManager um) throws Exception {
		User usr = um.getUserByUsername( TESTUSERNAME_PREFIX + (numRatings / 2) );
		long startMs = System.currentTimeMillis();
		t.getRating( usr );
		int ms = (int)(System.currentTimeMillis() - startMs);
		out.print( ms + "," );
		out.flush();
	}


	private void readAllRatings(PrintWriter out, Topic t) throws Exception {
		long startMs = System.currentTimeMillis();
		t.getRatings();
		int ms = (int)(System.currentTimeMillis() - startMs);
		out.print( ms + "," );
		out.flush();
	}
	
	
	private void generate10Ratings(PrintWriter out, Topic t, UserManager um) throws Exception {
		for (int i = 0; i < 10; i++) {
			User usr = um.getUserByUsername( TESTUSERNAME_PREFIX + numRatings );
			t.addRating( usr, Rating.NEUTRAL );
			numRatings++;
		}
		out.print( numRatings + "," );
		out.flush();
	}


	private void generateUsers(UserManager um) throws Exception {
		for (int i = 0; i < MAX_USERS; i++) {
			String username = TESTUSERNAME_PREFIX + i;
			um.createUser( username, username, null );
		}
	}

}
