/****************************************************************
 * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org)
 * =============================================================
 * License Information: http://lamsfoundation.org/licensing/lams/2.0/
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2.0 
 * as published by the Free Software Foundation.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 * 
 * http://www.gnu.org/licenses/gpl.txt
 * ****************************************************************
 */

/* $$Id: TestTwitterServicePOJO.java,v 1.18 2008/09/03 07:40:45 asukkar Exp $$ */
package org.lamsfoundation.lams.tool.twitter.service;

import java.util.Date;
import java.util.List;
import java.util.Iterator;


import org.lamsfoundation.lams.contentrepository.RepositoryCheckedException;
import org.lamsfoundation.lams.tool.twitter.TwitterApplicationException;
import org.lamsfoundation.lams.tool.twitter.TwitterDataAccessTestCase;
import org.lamsfoundation.lams.tool.twitter.TwitterContent;
import org.lamsfoundation.lams.tool.twitter.TwitterConstants;
import org.lamsfoundation.lams.tool.twitter.TwitterSession;
import org.lamsfoundation.lams.tool.twitter.TwitterUser;
import org.lamsfoundation.lams.tool.twitter.TwitterAttachment;
import org.lamsfoundation.lams.tool.twitter.service.ITwitterService;


/**
 * @author mtruong
 *
 */
public class TestTwitterServicePOJO extends TwitterDataAccessTestCase 
{
	
	private ITwitterService twitterService = null;
/*	private TwitterContent twitterContent;
	private TwitterSession twitterSession;
	private TwitterUser twitterUser; 
	private TwitterAttachment twitterAttachment;*/
	
	private boolean cleanContentData = true;

	
	public TestTwitterServicePOJO(String name)
	{
		super(name);
	}

	protected void setUp() throws Exception
	{
		super.setUp();
		
		twitterService = (ITwitterService)this.context.getBean("twitterService");
		initAllData();
		
	}
	
	protected void tearDown() throws Exception
	{
		//delete data
		if(cleanContentData)
        {
        	cleanTwitterContentData(TEST_NB_ID);
        }
       
	}
	
	/* ==============================================================================
	 * Methods for access to TwitterContent objects
	 * ==============================================================================
	 */
		
	public void testRetrieveTwitter()
	{
	    twitterContent = twitterService.retrieveTwitter(TEST_NB_ID);
		
	    assertContentEqualsTestData(twitterContent);
	
	}
	
	public void testUpdateTwitter()
	{
	    String newContent = "New updated content";
	    twitterContent = twitterService.retrieveTwitter(TEST_NB_ID);
	    twitterContent.setContent(newContent);
		
		//save the new changes
		twitterService.saveTwitter(twitterContent);
		
		//check whether the changes has been saved
		TwitterContent newTwitter = twitterService.retrieveTwitter(TEST_NB_ID);
		
		assertEquals(newTwitter.getTitle(), TEST_TITLE);
    	assertEquals(newTwitter.getContent(), newContent);
    	assertEquals(newTwitter.getOnlineInstructions(), TEST_ONLINE_INSTRUCTIONS);
    	assertEquals(newTwitter.getOfflineInstructions(), TEST_OFFLINE_INSTRUCTIONS);
    	assertEquals(newTwitter.isDefineLater(), TEST_DEFINE_LATER);
    	assertEquals(newTwitter.isForceOffline(), TEST_FORCE_OFFLINE);
    	assertEquals(newTwitter.getCreatorUserId(), TEST_CREATOR_USER_ID);
    	assertEquals(newTwitter.getDateCreated(), TEST_DATE_CREATED); 
	}
	
	public void testSaveTwitter()
	{
	    Long testToolContentId = new Long(8000);
		String testTitle = "TestCase: saveTwitter()";
		String testContent = "This is to test the saveTwitter() function";
		String testOnlineInstructions = "online instructions";
		String testOfflineInstructions = "offline instructions";
		
		TwitterContent content = new TwitterContent(testToolContentId,
		        											testTitle,
		        											testContent,
		        											testOnlineInstructions,
		        											testOfflineInstructions,
		        											new Date(System.currentTimeMillis()));
		twitterService.saveTwitter(content);
		
		TwitterContent retrievedObject = twitterService.retrieveTwitter(testToolContentId);
		assertEquals(retrievedObject.getTitle(), testTitle);
		assertEquals(retrievedObject.getContent(), testContent);
		assertEquals(retrievedObject.getOnlineInstructions(), testOnlineInstructions);
		assertEquals(retrievedObject.getOfflineInstructions(), testOfflineInstructions);
		
		//remove test data
		
		twitterService.removeTwitter(testToolContentId);
	}
	
	public void testremoveTwitterSessions()
	{
	    twitterContent = twitterService.retrieveTwitter(TEST_NB_ID);
	    
	    twitterService.removeTwitterSessionsFromContent(twitterContent);
	    
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    assertNull(twitterSession);
	    
	} 
	
	public void testRemoveTwitterByID()
	{
	    cleanContentData = false;
	    twitterService.removeTwitter(TEST_NB_ID);
	    
	    TwitterContent twitter = twitterService.retrieveTwitter(TEST_NB_ID);
	    assertNull(twitter);
	}
	
	public void testRemoveTwitter()
	{
	    cleanContentData = false;
	    twitterService.removeTwitter(twitterService.retrieveTwitter(TEST_NB_ID));
	    
	    TwitterContent twitter = twitterService.retrieveTwitter(TEST_NB_ID);
	    assertNull(twitter);
	}
	
	/* ==============================================================================
	 * Methods for access to TwitterSession objects
	 * ==============================================================================
	 */
	
	public void testRetrieveTwitterSession()
	{
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    assertEqualsForSessionContent(twitterSession);
	}
	
	
	public void testSaveTwitterSession()
	{
	    Long testSessionId = new Long(9000);
	    Long testContentId = new Long(9500);
	    Date created = new Date(System.currentTimeMillis());
	    
	    TwitterContent twitterContent = new TwitterContent();
	    twitterContent.setTwitterContentId(testContentId);
	    twitterService.saveTwitter(twitterContent);
	    
	   TwitterSession twitterSession = new TwitterSession(testSessionId,
			   													"Session "+testSessionId,
	            												twitterContent,
	            												created,
	            												TwitterSession.NOT_ATTEMPTED); 
	    twitterService.addSession(testContentId, twitterSession);
	 
	    
	   	TwitterSession retrievedSession = twitterService.retrieveTwitterSession(testSessionId);
	    
	    assertEquals(retrievedSession.getTwitterContent().getTwitterContentId(), testContentId);
	    assertEquals(retrievedSession.getSessionStartDate(), created);
	    assertEquals(retrievedSession.getSessionStatus(), TwitterSession.NOT_ATTEMPTED);
	    
	    //remove test data
	    twitterService.removeTwitter(testContentId);
	}
	
	public void testUpdateTwitterSession()
	{
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	   	Date date = new Date(System.currentTimeMillis());
	   
	   	twitterSession.setSessionStatus(TwitterSession.COMPLETED);
	   	twitterSession.setSessionEndDate(date);
	   	
	   	twitterService.updateTwitterSession(twitterSession);
	   	
	   	TwitterSession retrievedSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	   	
	   	assertEquals(retrievedSession.getSessionStatus(), TwitterSession.COMPLETED);
	   	assertEquals(retrievedSession.getSessionEndDate(), date);
	}
	
	public void testRemoveSessionByID()
	{
	 
	    twitterService.removeSession(TEST_SESSION_ID);
	 	    
	    assertSessionObjectIsNull(TEST_SESSION_ID);
	}
	
	public void testRemoveSession()
	{
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    
	    twitterService.removeSession(twitterSession);
		    
	    assertSessionObjectIsNull(TEST_SESSION_ID);
	    
	}
	
	public void testRemoveTwitterUsersFromSession()
	{
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);	    
	    
	    twitterService.removeTwitterUsersFromSession(twitterSession);
	    
	    twitterUser = twitterService.retrieveTwitterUser(TEST_USER_ID, TEST_SESSION_ID);

	    assertNull(twitterUser);
	    
	}
	
	/* ==============================================================================
	 * Methods for access to TwitterUser objects
	 * ==============================================================================
	 */
	public void testRetrieveTwitterUser()
	{
	    twitterUser = twitterService.retrieveTwitterUser(TEST_USER_ID, TEST_SESSION_ID);
	    
	    assertEqualsForTwitterUser(twitterUser);
	}

	
	public void testSaveTwitterUser()
	{
	    Long newUserId = new Long(8756);
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    
	    TwitterUser user = new TwitterUser(newUserId, twitterSession);
	    
	  
	    twitterService.saveTwitterUser(user);
	    
	    TwitterUser userInDb = twitterService.retrieveTwitterUser(newUserId, TEST_SESSION_ID);
	    assertEquals(userInDb.getUserId(), newUserId);
	    assertEquals(userInDb.getTwitterSession().getTwitterSessionId(), TEST_SESSION_ID);
	}
	
	public void testUpdateTwitterUser()
	{
	    twitterUser = twitterService.retrieveTwitterUser(TEST_USER_ID, TEST_SESSION_ID);
	    twitterUser.setUserStatus(TwitterUser.COMPLETED);
	    
	    twitterService.updateTwitterUser(twitterUser);
	    
	    TwitterUser updatedUser = twitterService.retrieveTwitterUser(TEST_USER_ID, TEST_SESSION_ID);
	    
	    assertEquals(updatedUser.getUserStatus(), TwitterUser.COMPLETED);
	}
	
	public void testRemoveUserById()
	{
	  
	    twitterService.removeUser(TEST_USER_ID, TEST_SESSION_ID);
	    
	    assertUserObjectIsNull(TEST_USER_ID);
	  
	}
	
	public void testRemoveUser()
	{
	    twitterUser = twitterService.retrieveTwitterUser(TEST_USER_ID, TEST_SESSION_ID);
	
	    twitterService.removeUser(twitterUser);
	    
	    assertUserObjectIsNull(TEST_USER_ID);
	  
	}
	
	public void testAddSession()
	{
	    Long toolSessionId = new Long(99);
	    TwitterSession newSession = new TwitterSession(toolSessionId);
        twitterService.addSession(TEST_NB_ID, newSession);
        
        TwitterSession session = twitterService.retrieveTwitterSession(toolSessionId);
        assertEquals(session.getTwitterContent().getTwitterContentId(), TEST_NB_ID);
       
	}
	
	public void testAddUser()
	{
	    Long userId = new Long(88);
	    TwitterUser newUser = new TwitterUser(userId);
        twitterService.addUser(TEST_SESSION_ID, newUser);
        
        TwitterUser user = twitterService.retrieveTwitterUser(userId, TEST_SESSION_ID);
        assertEquals(user.getTwitterSession().getTwitterSessionId(), TEST_SESSION_ID);
	}
	
	public void testGetSessionIdsFromContent()
	{
	    TwitterContent content = twitterService.retrieveTwitter(TEST_NB_ID);
	    List list = twitterService.getSessionIdsFromContent(content);
	    
	    assertEquals(list.size(), 1);
	    Iterator i = list.iterator();
        
        while (i.hasNext())
        {
            Long sessionID = (Long)i.next();
            assertEquals(sessionID, TEST_SESSION_ID);
        }
	}
	
	public void testGetNumberOfUsersInSession()
	{
	    TwitterSession session = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    int numberOfUsers = twitterService.getNumberOfUsersInSession(session);
	    assertEquals(numberOfUsers, 1);
	    
	    //now add more users in the session
	    Long userId1 = new Long(34);
	    Long userId2 = new Long(35);
	    TwitterUser user1 = new TwitterUser(userId1, session);
	    TwitterUser user2 = new TwitterUser(userId2, session);
	    twitterService.saveTwitterUser(user1);
	    twitterService.saveTwitterUser(user2);
	    
	    //now retrieve and there should be 3 users for this session
	    twitterSession = twitterService.retrieveTwitterSession(TEST_SESSION_ID);
	    int newNumberOfUsers = twitterService.getNumberOfUsersInSession(twitterSession);
	    assertEquals(newNumberOfUsers, 3);
	    
	  //  int totalNumberOfLearners = twitterService.calculateTotalNumberOfUsers(TEST_NB_ID);
	    //assertEquals(totalNumberOfLearners, 3);
	}
	



	public void testCalculateTotalNumberOfUsers()
	{
	    /* add more sessions relating to the test tool content id and add more users in each session
	     * then calculate the total number of users for this tool activity
	     */
	    Long sessionId1, sessionId2, sessionId3;
	    Long userId1, userId2, userId3, userId4, userId5, userId6;
	    TwitterSession session1, session2, session3;
	    TwitterUser user1Sess1, user2Sess1, user3Sess1, user4Sess2, user5Sess2, user6Sess3;
	    twitterContent = twitterService.retrieveTwitter(TEST_NB_ID);
	    //create more sessions
	    sessionId1 = new Long(456); sessionId2 = new Long(457); sessionId3 = new Long(458);
	    userId1 = new Long(567); userId2 = new Long(568); userId3 = new Long(569);
	    userId4 = new Long(570); userId5 = new Long(571); userId6 = new Long(572);
	    
	    session1 = new TwitterSession(sessionId1, "Session "+sessionId1, twitterContent);
	    session2 = new TwitterSession(sessionId2, "Session "+sessionId1, twitterContent);
	    session3 = new TwitterSession(sessionId3, "Session "+sessionId1, twitterContent);
	    
	    twitterContent.getTwitterSessions().add(session1);
	    twitterContent.getTwitterSessions().add(session2);
	    twitterContent.getTwitterSessions().add(session3);
	    
	    twitterService.saveTwitter(twitterContent);
	    
	    user1Sess1 = new TwitterUser(userId1, session1);
	    user2Sess1 = new TwitterUser(userId2, session1);
	    user3Sess1 = new TwitterUser(userId3, session1);
	    user4Sess2 = new TwitterUser(userId4, session2);
	    user5Sess2 = new TwitterUser(userId5, session2);
	    user6Sess3 = new TwitterUser(userId6, session3);
	    
	    session1.getTwitterUsers().add(user1Sess1);
	    session1.getTwitterUsers().add(user2Sess1);  
	    session1.getTwitterUsers().add(user3Sess1);
	    
	    session2.getTwitterUsers().add(user4Sess2);
	    session2.getTwitterUsers().add(user5Sess2);
	    
	    session3.getTwitterUsers().add(user6Sess3);
	    
	    twitterService.saveTwitterSession(session1);
	    twitterService.saveTwitterSession(session2);
	    twitterService.saveTwitterSession(session3);
	    

	    //now test the function
	    int totalUsers = twitterService.calculateTotalNumberOfUsers(TEST_NB_ID);
	    assertEquals("testing the total number of users", totalUsers, 7);
	    
	    
	}







/* ==============================================================================
	 * Methods for access to TwitterAttachment objects
	 * ==============================================================================
	 */
	
	public void testRetrieveAttachment()
	{
	    initTwitterAttachmentData();
	    //test retrieveAttachmentByUuid
	    twitterAttachment = twitterService.retrieveAttachmentByUuid(TEST_UUID);
	    
	    assertAttachmentData(twitterAttachment);
	    /* test getAttachmentsFromContent which will return a list of twitterAttachment ids, which we can use in the next method call to
	     retrieveAttachment which takes in the attachmentId as the parameter. */
	    List idList = twitterService.getAttachmentIdsFromContent(twitterService.retrieveTwitter(TEST_NB_ID));
	    
	    //test retrieveAttachment (by attachmentId, which was retrieved from the previous method)
	    twitterAttachment = twitterService.retrieveAttachment((Long)idList.get(0));
	    assertAttachmentData(twitterAttachment);
	    
	    //test retrieveAttachmentByFilename;
	    twitterAttachment = twitterService.retrieveAttachmentByFilename(TEST_FILENAME);
	    assertAttachmentData(twitterAttachment);
	}
	
	 public void testRetrieveAttachmentWithNullParameters() throws TwitterApplicationException
	 {
	     //retrieve twitterAttachment by filename
	     try
	     {
	         twitterService.retrieveAttachmentByFilename(null);
	         fail("An exception should have been thrown as a null value has been given for the argument");
	     }
	     catch (TwitterApplicationException e)
	     {
	         assertTrue(true);
	     }
	     
	     //retrieve twitterAttachment by twitterAttachment id
	     try
	     {
	         twitterService.retrieveAttachment(null);
	         fail("An exception should have been thrown as a null value has been given for the argument");
	     }
	     catch (TwitterApplicationException e)
	     {
	         assertTrue(true);
	     }
	     
	     //retrieve twitterAttachment by uuid
	     try
	     {
	         twitterService.retrieveAttachmentByUuid(null);
	         fail("An exception should have been thrown as a null value has been given for the argument");
	     }
	     catch (TwitterApplicationException e)
	     {
	         assertTrue(true);
	     }
	     
	 }
	
	public void testSaveAttachment()
	{
	  /*  String newFilename = "TwitterInstructions.txt";
	    initTwitterAttachmentData();
	    
	    twitterAttachment = twitterService.retrieveAttachmentByUuid(TEST_UUID);
	    twitterAttachment.setFilename(newFilename);
	    
	    twitterService.saveAttachment(twitterAttachment);
	    
	    twitterAttachment = twitterService.retrieveAttachmentByUuid(TEST_UUID);
	    assertEquals(twitterAttachment.getFilename(), newFilename); */
	    String filename = "OnlineInstructions.txt";
	    boolean isOnline = true;
	    Long uuid = new Long(2);
	    
	    TwitterAttachment file = new TwitterAttachment();
	    twitterContent = twitterService.retrieveTwitter(TEST_NB_ID);
	    file.setTwitterContent(twitterContent);
	    file.setFilename(filename);
	    file.setOnlineFile(isOnline);
	    file.setUuid(uuid);
	    
	    twitterService.saveAttachment(twitterContent, file);
	    
	}
	
/* This method fails because the attachment isnt really uploaded to the content repository sow hen it tries to delete from repository it fails */
		
	/*public void testRemoveAttachment() 
	{
	    initTwitterAttachmentData();
	    twitterAttachment = twitterService.retrieveAttachmentByUuid(TEST_UUID);
	    
	    try {
			twitterService.removeAttachment(twitterService.retrieveTwitter(TEST_NB_ID), twitterAttachment);
		} catch (RepositoryCheckedException e) {
			fail("Repository exception thrown"+e.getMessage());
		}
	   
	    twitterAttachment = twitterService.retrieveAttachmentByUuid(TEST_UUID);
	    
	    assertNull(twitterAttachment);
	    
	} */
	
	/*public void testGetToolDefaultContentIdBySignature()
	{
	    Long defaultToolContentId = twitterService.getToolDefaultContentIdBySignature(TwitterConstants.TOOL_SIGNATURE);
	    assertNotNull(defaultToolContentId);
	} */
	
	public void testRetrieveTwitterUserBySession()
	{
		 Long newSessionId1 = new Long(3457);
		 TwitterSession newSession1 = new TwitterSession(newSessionId1);
	     twitterService.addSession(TEST_NB_ID, newSession1);
	     
	     TwitterUser oldUserInSession1 = new TwitterUser(TEST_USER_ID, newSession1);
	     twitterService.saveTwitterUser(oldUserInSession1);
	     
	     //associate the same test user to another new session
	     Long newSessionId2 = new Long(3458);
		 TwitterSession newSession2 = new TwitterSession(newSessionId2);
	     twitterService.addSession(TEST_NB_ID, newSession2);
	     
	     TwitterUser oldUserInSession2 = new TwitterUser(TEST_USER_ID, newSession2);
	     twitterService.saveTwitterUser(oldUserInSession2);
	     
	     //create another user in one of the existing sessions
	     Long newUserId = new Long(3459);
	     TwitterUser user2 = new TwitterUser(newUserId, newSession1);
	     twitterService.saveTwitterUser(user2);
	     
	     //try to get the test user using newSessionId1
	     twitterUser = twitterService.retrieveTwitterUserBySession(TEST_USER_ID, newSessionId1);
	     assertEquals(twitterUser.getUserId(), TEST_USER_ID);
	     assertEquals(twitterUser.getTwitterSession().getTwitterSessionId(), newSessionId1);
	     
	     //try to get the test user using newSessionId2
	     twitterUser = twitterService.retrieveTwitterUserBySession(TEST_USER_ID, newSessionId2);
	     assertEquals(twitterUser.getUserId(), TEST_USER_ID);
	     assertEquals(twitterUser.getTwitterSession().getTwitterSessionId(), newSessionId2);
	     
	     //try to get the new user that was created
	     twitterUser = twitterService.retrieveTwitterUserBySession(newUserId, newSessionId1);
	     assertEquals(twitterUser.getUserId(), newUserId);
	     assertEquals(twitterUser.getTwitterSession().getTwitterSessionId(), newSessionId1);
	     
	     //try to get data that does not exist, should return null
	     twitterUser = twitterService.retrieveTwitterUserBySession(newUserId, newSessionId2);
	     assertNull(twitterUser);
	     
	
	}
		
}
	
	
