package net.sourceforge.jsurveyor;
import java.util.*;
import junit.framework.*;

/**
 * Junit test.
 * 
 * @version 1.0
 * @author Claus Methmann Christensen
 * @author Anders Spliid Hansen
 * @author Esben Iversen Hansen
 * @author Lars H Jensen
 * @author Marcus Overheu
 * @author Thomas Ramdal
 * @author Peter Thomsen
 */
public class TestOrDie extends TestCase {

	/**
	 * Field an1
	 */
	protected Answer an1, an2;
	/**
	 * Field u1
	 */
	protected User u1, u2, u3;
	/**
	 * Field g1
	 */
	protected UserGroup g1, g2;
	/**
	 * Field a1
	 */
	protected AccessControl a1, a2;
	/**
	 * Field q1
	 */
	protected QuestionMultipleChoice q1;
	/**
	 * Field q2
	 */
	protected QuestionFreeText q2;
	/**
	 * Field aM1
	 */
	protected AnswerMultipleChoice aM1;
	/**
	 * Field aF1
	 */
	protected AnswerFreeText aF1;
	/**
	 * Field tempArrayList
	 */
	protected Questionnaire Qu1;
	
	protected ArrayList tempArrayList;

	/**
	 * Method setUp
	 */
	protected void setUp() {
		u2 =
			new User(
				"hornbaek",
				"password",
				"normal",
				"hornbaek@cs.auc.dk",
				"Lars H Jensen",
				"Aalborg",
				"Denmark");

		u1 =
			new User(
				"lhj",
				"password",
				"normal",
				"lhj@cs.auc.dk",
				"Lars H Jensen",
				"Aalborg",
				"Denmark");

		u3 =
			new User(
				"spliid",
				"password",
				"normal",
				"nospam@for.me",
				"Anders Spliid Hansen",
				"Aalborg",
				"Denmark");

		g1 = new UserGroup("DAT1");
		g2 = new UserGroup("CS");

		q1 =
			new QuestionMultipleChoice(
				"hvordan synes du selv det g�r",
				new String[] {
					"choice0",
					"choice1",
					"choice2",
					"choice3",
					"choice4",
					"choice5",
					"choice6",
					"choice7" },
				true);

		int aM1questionID = 666, aF1questionID = 999;
		int aM1choice = 2;
		String aF1freeText = new String("Good evaluation");
		int Qu1ID = 666;
		
		aM1 = new AnswerMultipleChoice(aM1questionID , aM1choice);
		aF1 = new AnswerFreeText(aF1questionID, aF1freeText);
		Qu1 = new Questionnaire();
		Qu1.setQuestionnaireID(Qu1ID);
		
		
		q2 = new QuestionFreeText("tomt sp�rgsm�l", true);
		q2 = new QuestionFreeText("tomt sp�rgsm�l", true);

	}

	/**
	 * Method testUserGroupsStorage exercises UserGroup storage & adding and
	 * removing childrens and parents
	 */
	public void testUserGroupsStorage() {

		DataAccess.storeUserGroup(g1);
		DataAccess.storeUserGroup(g2);
		DataAccess.storeUser(u1);
		DataAccess.storeUser(u2);

		// ved en addParent eller addChild operation skal begge objekter
		//efterfølgende gemmes
		u1.addParent(g1);
		DataAccess.storeUser(u1);
		DataAccess.storeUserGroup(g1);

		u1.addParent(g2);
		DataAccess.storeUser(u1);
		DataAccess.storeUserGroup(g2);
		System.out.println(
			"About to delete Usergroup "
				+ g2.getGroupName()
				+ ", where "
				+ u1.getUserName()
				+ " was added as child");

		System.out.println(
			"User "
				+ u1.getUserName()
				+ "'s parents before: "
				+ u1.getRefParents());

		DataAccess.deleteUserGroup(g2.getUserGroupID());
		// efter en deleteUserGroup skal objekterne IGEN :( hentes fra DB
		//				u1 = DataAccess.retrieveUser(u1.getUserName());

		System.out.println(
			"User "
				+ u1.getUserName()
				+ "'s parents after: "
				+ u1.getRefParents());

		System.out.print("Delete User u1 :");
		DataAccess.deleteUser(u1.getUserName());
		g2.addChild(g1);

		g1.addChild(u2);
		u2.addParent(g2);

		System.out.println("Group G1's ID: " + g1.getUserGroupID());
		System.out.println("Group G2's ID: " + g2.getUserGroupID());

		DataAccess.deleteUser(u2.getUserName());
		DataAccess.deleteUserGroup(g1.getUserGroupID());
		DataAccess.deleteUserGroup(g2.getUserGroupID());
	}

	// exercise Answer components and corresponding DataAccess methods
	/**
	 * Method testAnswer
	 */
	public void testAnswer() {

		try {
			q1.addChoice(new String[] { "a", "b", "c", "d" }, 4);
		} catch (IllegalAccessException e) {
			System.out.println(e);
		}

		DataAccess.storeQuestion(q1);
		System.out.println(q1);
		System.out.println(DataAccess.retrieveQuestion(q1.getQuestionID()));

		DataAccess.storeQuestion(q2);
		System.out.println(q2);
		System.out.println(DataAccess.retrieveQuestion(q2.getQuestionID()));

		DataAccess.deleteQuestion(q1.getQuestionID());
		DataAccess.deleteQuestion(q2.getQuestionID());
	}

	//exercise User components and corresponding DataAccess methods
	public void testUser() throws ClassNotFoundException {

		System.out.println(
			"Testing user--------------------------------------");

		DataAccess.storeUserGroup(g1);
		DataAccess.storeUserGroup(g2);

		assertFalse(DataAccess.existsUser("sdfe4sdf"));

		System.out.println("Group g1: " + g1);
		u1.addParent(g1);
		u1.addParent(g2);
		DataAccess.storeUser(u1);
		DataAccess.storeUserGroup(g1);
		DataAccess.storeUserGroup(g2);

		g2.addChild(u2);
		g1.addParent(g2);
		DataAccess.storeUser(u2);
		DataAccess.storeUserGroup(g1);
		DataAccess.storeUserGroup(g2);

		System.out.println(
			"refParents: "
				+ u1.getRefParents()
				+ "\tparents: "
				+ u1.getParents());
		System.out.println("u1 has the following parents " + u1.getParents());
		System.out.println("g2 has the following childs" + g2.getRefChildren());
		System.out.println("Removing u2 from g2");

		u2.removeParent(g2);
		DataAccess.storeUser(u2);
		DataAccess.storeUserGroup(g2);

		System.out.println("g2 has the following childs" + g2.getRefChildren());
		System.out.println("g1 has the following childs" + g1.getRefChildren());
		System.out.println("Removing u1 from g1");

		g1.removeChild(u1);
		DataAccess.storeUser(u1);
		DataAccess.storeUserGroup(g1);

		System.out.println("g1 has the following childs" + g1.getRefChildren());

		g1.addChild(u1);
		g1.addChild(u2);
		g1.addChild(g2);
		DataAccess.storeUser(u1);
		DataAccess.storeUser(u2);
		DataAccess.storeUserGroup(g1);
		DataAccess.storeUserGroup(g2);

		assertTrue(u1.isEmailValid());
		u1.setEmail("thisisnotvalid");
		assertFalse(u1.isEmailValid());

		u2.removeParent(g1);
		DataAccess.storeUser(u2);
		DataAccess.storeUserGroup(g1);

		u2.setEmail("lhj@cs.auc.dk");
		assertTrue(u2.isEmailValid());

		System.out.println(
			"The following users is in the database: "
				+ DataAccess.retrieveAllUsers());
		System.out.println(
			"Password for admin - "
				+ DataAccess.retrieveUser("admin").getPassword());

		// cleaning up

		DataAccess.deleteUserGroup(g1.getUserGroupID());
		DataAccess.deleteUserGroup(g2.getUserGroupID());
		DataAccess.deleteUser(u1.getUserName());
		DataAccess.deleteUser(u2.getUserName());
	} // end testUser

	// exercise Question components
	public void testQuestion() {
		System.out.println(
			"Testing Question----------------------------------");
		try {
			q1.removeChoice(5);
		} catch (IllegalAccessException e) {
		}

		try {
			q1.addChoice(new String[] { "a", "b", "c", "d" }, 4);
		} catch (IllegalAccessException e) {
			System.out.println(e);
		}
	} // end testAdd2

	public void testEvaluation() {
		System.out.println("Testing Evaluation--------------");
		int evaluationID = 666;
		String userName = new String ("testUserName");
		int questionnaireID = Qu1.getQuestionnaireID();
		Evaluation testEval = new Evaluation(evaluationID, userName, questionnaireID);
		long date = 11223344;
		Date time = new Date(date);
		testEval.setTimestamp(time);
		testEval.setTimestamp(time);
		testEval.addAnswer(aM1);
		testEval.addAnswer(aF1);
		int numberAnswers = 2;
		
		//test the created evaluation
		System.out.println("\n Testing Created Evaluation");
		System.out.println("Number of answers should be "+ numberAnswers  + ": " + testEval.getAnswerSize());
		System.out.println("EvaluationID: " + testEval.getEvaluationID());
		System.out.println("QuestionnaireID: " + testEval.getQuestionnaireID());
		System.out.println("Timestamp: " + testEval.getTimestamp());
		System.out.println("UserName: " + testEval.getUserName());
		for(int i = 0; i < testEval.getAnswerSize(); i++){
		System.out.println("Answer "+ i +": "+ testEval.getAnswers());
		}
		//Saving the evaluation
		System.out.println("\n Saving Evaluation ");
		DataAccess.storeEvaluation(testEval);
		//retrieves the evaluation
		System.out.println("\n Retrieving Evaluation");  
		Evaluation retTestEval = (Evaluation) DataAccess.retrieveEvaluation(666);
		//test the retrieved evaluation
		System.out.println("\n Test of retrieved Evaluation \n ");
		System.out.println("Number of answers should be "+ numberAnswers  + ": " + retTestEval.getAnswerSize());
		System.out.println("EvaluationID: " + retTestEval.getEvaluationID());
		System.out.println("QuestionnaireID: " + retTestEval.getQuestionnaireID());
		System.out.println("Timestamp: " + retTestEval.getTimestamp());
		System.out.println("UserName: " + retTestEval.getUserName());
		for(int i = 0; i < retTestEval.getAnswerSize(); i++){
			System.out.println("Answer "+ i +": "+ retTestEval.getAnswers());
		}
	}

	public void testQuestionnaire() {
		System.out.println(
			"Testing Questionnaire -----------------------------");
		System.out.println("Extensive testing have already been done");
		System.out.println("And everything regarding to questionnaires,");
		System.out.println("can be done through the web interface");
		System.out.println(
			"This restriction is to ensure correctness of the DB");
		User master =
			new User(
				"Test-user",
				"password",
				"admin",
				"hornbaek@cs.auc.dk",
				"Lars H Jensen",
				"Aalborg",
				"Denmark");

		Questionnaire a =
			new Questionnaire(master.toString(), "SAD evaluering");
		System.out.println("The questionnaire before storing:");
		System.out.println(a);
		DataAccess.storeQuestionnaire(a);
		System.out.println("The questionnaire after storing:");
		System.out.println(a);
		QuestionPage firstPage = new QuestionPage();
		QuestionPage secondPage = new QuestionPage();
		QuestionPage thirdPage = new QuestionPage();
		System.out.println("Before saving questionPages--");
		System.out.println(firstPage);
		System.out.println(secondPage);
		System.out.println(thirdPage);
		DataAccess.storeQuestionPage(firstPage);
		DataAccess.storeQuestionPage(secondPage);
		DataAccess.storeQuestionPage(thirdPage);
		System.out.println("After saving questionPages--");
		System.out.println(firstPage);
		System.out.println(secondPage);
		System.out.println(thirdPage);
		a.addQuestionPage(secondPage);
		a.addQuestionPageAtPosition(firstPage, 0);
		a.addQuestionPage(thirdPage);
		System.out.println(a.getRefQuestionPages());
		System.out.println("Moving page 3 up:");
		a.removeQuestionPage(thirdPage);
		a.addQuestionPageAtPosition(thirdPage, 1);
		System.out.println(a.getRefQuestionPages());
		DataAccess.storeQuestionnaire(a);
		Questionnaire b =
			DataAccess.retrieveQuestionnaire(a.getQuestionnaireID());
		System.out.println("The retrieved Questionnaire looks like this:");
		System.out.println(b);
		QuestionPage firstP =
			DataAccess.retrieveQuestionPage(firstPage.getQuestionPageID());
		QuestionPage secondP =
			DataAccess.retrieveQuestionPage(secondPage.getQuestionPageID());
		QuestionPage thirdP =
			DataAccess.retrieveQuestionPage(thirdPage.getQuestionPageID());
		System.out.println("The retrieved QuestionPages looks like this:");
		System.out.println("" + firstP + " " + secondP + " " + thirdP);
		QuestionFreeText firstQuestion = new QuestionFreeText();
		DataAccess.storeQuestion(firstQuestion);
		QuestionMultipleChoice secondQuestion = new QuestionMultipleChoice();
		DataAccess.storeQuestion(secondQuestion);
		System.out.println(
			"Our two questions: " + firstQuestion + " " + secondQuestion);
		try {
			firstQuestion.setText("Is this fancy or what?");
			firstQuestion.setWriteable(false);
			System.out.println("Question was altered succesfully.");
		} catch (IllegalAccessException e) {
			System.out.println(
				"The question: " + firstQuestion + "\nwas not writeable.");
		}
		DataAccess.storeQuestion(firstQuestion);
		String[] choices = new String[4];
		choices[0] = "daarlig";
		choices[1] = "ok";
		choices[2] = "godt";
		choices[3] = "det bedste";
		try {
			secondQuestion.setChoice(choices);
			secondQuestion.setText("Hvordan vil du vurdere JSurveyor?");
			System.out.println("Choices was added succesfully.");
		} catch (IllegalAccessException e) {
			System.out.println(
				"The question: " + secondQuestion + " was not writeable.");
		}
		secondQuestion.setWriteable(false);
		try {
			secondQuestion.setChoice(choices);
			System.out.println("Choices was added succesfully.");
		} catch (IllegalAccessException e) {
			System.out.println(
				"The question: " + secondQuestion + "\nwas not writeable.");
		}

		DataAccess.storeQuestion(secondQuestion);
		firstPage.addQuestion(firstQuestion);
		firstPage.addQuestion(secondQuestion);
		DataAccess.storeQuestionPage(firstPage);
		System.out.println("Questions has beed added to firstPage:");
		System.out.println(firstPage.getRefQuestions());
		System.out.println("Questionnaire before removal of " + thirdPage);
		System.out.println(a.getRefQuestionPages());
		a.removeQuestionPage(thirdPage);
		DataAccess.storeQuestionnaire(a);
		System.out.println("Questionnaire after removal of " + thirdPage);
		System.out.println(a.getRefQuestionPages());
		DataAccess.deleteQuestionPage(thirdPage.getQuestionPageID());
		QuestionFreeText thirdQuestion = new QuestionFreeText();
		DataAccess.storeQuestion(thirdQuestion);
		try {
			thirdQuestion.setText("Hvorfor mener du at JSurveyor er daarligt?");
			int[] temp = new int[1];
			temp[0] = 0;
			thirdQuestion.setDependency(secondQuestion, temp);
			System.out.println("Question with dependency made");
		} catch (IllegalAccessException e) {
			System.out.println(
				"The question: " + thirdQuestion + "\nwas not writeable.");
		}
		DataAccess.storeQuestion(thirdQuestion);
		secondPage.addQuestion(thirdQuestion);
		DataAccess.storeQuestionPage(secondPage);

		ArrayList tempList = DataAccess.retrieveQuestionnairesForOwner(master);
		System.out.println(
			"The user " + master + " owns the following questionnaires:");
		System.out.println(tempList);

		DataAccess.deleteQuestionnaire(a.getQuestionnaireID());
		DataAccess.deleteQuestionPage(firstPage.getQuestionPageID());
		DataAccess.deleteQuestionPage(secondPage.getQuestionPageID());
		DataAccess.deleteQuestion(firstQuestion.getQuestionID());
		DataAccess.deleteQuestion(secondQuestion.getQuestionID());

	}

	/**
	 * Method intsToString
	 * 
	 * @param testString
	 *                    int[]
	 * @return String
	 */
	String intsToString(int[] testString) {
		String returnString = new String("");
		for (int i = 0; i < testString.length; i++) {
			returnString =
				returnString + " " + java.lang.Integer.toString(testString[i]);
		}

		return returnString;
	}

	/**
	 * Method stringsToString
	 * 
	 * @param testString
	 *                    String[]
	 * @return String
	 */
	String stringsToString(String[] testString) {
		String returnString = new String("");
		for (int i = 0; i < testString.length; i++) {
			returnString = returnString + " " + testString[i];
		}

		return returnString;
	}

	/**
	 * Method testReport
	 */
	public void testReport() {
		System.out.println("Testing report---------------------------------");
		int questionnaireID = 340;

		Report repTest = new Report(questionnaireID);
		System.out.println(
			"Number of evaluations: " + repTest.getAllEvaluationsSize());
		System.out.println(
			"Number of usable evaluations: "
				+ repTest.getUsableEvaluationsSize());
		System.out.println(
			"Number of InnerAnswerMultipleChoice: "
				+ repTest.getInnerAnswerMultipleChoiceSize());
		System.out.println(
			"Number of InnerQuestionFreeText:  "
				+ repTest.getInnerFreeTextSize());
		System.out.println("\n Test all innerQuestionFreeText \n \n");
		for (int i = 0; i < repTest.getInnerFreeTextSize(); i++) {
			System.out.println(
				"QuestionText for this InnerQuestionFreeText: "
					+ repTest.getInnerQuestionFreeText(i));
			System.out.println(
				"Number of answers to this Question: "
					+ repTest.getInnerAnswerSize(i));
		}

		System.out.println("\n Test all innerAnswerMultipleChoice \n \n");
		for (int i = 0; i < repTest.getInnerAnswerMultipleChoiceSize(); i++) {
			System.out.println(
				"QuestionText: " + repTest.getInnerAnswerMultipleChoiceText(i));
			System.out.println(
				"By output choices exist:  "
					+ repTest.getInnerAnswerMultipleChoiceQuestionText(i));
			System.out.println(
				"By output distribution exist "
					+ repTest.getInnerAnswerMultipleChoiceDistribution(i));
		}
	}

	/**
	 * Method main
	 * 
	 * @param args
	 *                    String[]
	 */
	public static void main(String[] args) {
		junit.textui.TestRunner.run(suite());
	}

	/**
	 * Method suite
	 * 
	 * @return Test
	 */
	public static Test suite() {
		return new TestSuite(TestOrDie.class);
	}

}