package com.agilex.vamf.missionhealth.datalayer;


import com.agilex.vamf.missionhealth.domain.*;
import com.agilex.vamf.missionhealth.domain.comparator.MissionHealthDetailStandingComparator;
import com.agilex.vamf.missionhealth.domain.enumeration.MissionStatus;
import com.agilex.vamf.missionhealth.service.*;
import com.agilex.vamf.missionhealth.service.enumeration.NotificationType;
import com.agilex.vamf.utils.DateHelper;
import com.mongodb.*;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import javax.annotation.Resource;

import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class MissionHealthTaskServiceTest extends SpringBasedIntegrationRepo {
   	
	@Resource
	MissionHealthDataService missionHealthDataService;

    @Resource
    MissionHealthTaskService missionHealthTaskService;
	
	@Resource
	PointService pointService;

    private static final String missionhealthdb = "missionhealthdb";
    private static final String missionhealthdetails = "missionhealthdetails";

    private static final String Air_Force = "Air Force";
    private static final String Army = "Army";
    private static final String Coast_Guard = "Coast Guard";
    private static final String Marines = "Marines";
    private static final String Navy = "Navy";

    private PatientIdentifier lazyPatientId;
    private PatientIdentifier activePatientId;
    private PatientIdentifier otherPatientId;

    @Before
    public void clearPreviousTestData(){
        lazyPatientId = new PatientIdentifier("EDIPI", "lazyPatient");
        activePatientId = new PatientIdentifier("EDIPI", "activePatient");
        otherPatientId = new PatientIdentifier("EDIPI", "otherPatient");
    }

    @Test
    public void triggerWeeklyTasksTest(){
        missionHealthTaskService.triggerWeeklyTasks();
        MissionHealthWeeklyStatus status = missionHealthDataService.missionHealthDataLayer.startWeeklyTasks();
        int retries = 0;
        while(null==status && retries<300){
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            status = missionHealthDataService.missionHealthDataLayer.startWeeklyTasks();
            retries++;
        }
        Assert.assertNotNull(status);
        Assert.assertEquals(MissionHealthWeeklyStatus.PROCESSING, status.getStatus());
        status.setComplete(true);
        status.setStatus(MissionHealthWeeklyStatus.SUCCESS);
        status.setCompleteDatetime(new Date());
        missionHealthDataService.missionHealthDataLayer.saveMissionHealthWeeklyStatus(status);

        Assert.assertNull(missionHealthDataService.missionHealthDataLayer.startWeeklyTasks());
    }
    @Test
    public void triggerNotificationTasksTest(){
        missionHealthTaskService.triggerDailyReminder();
        missionHealthTaskService.triggerMidWeekReminder();
        missionHealthTaskService.triggerEndWeekReminder();

        MissionHealthNotificationStatus dailyStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_DAILY.toString());
        MissionHealthNotificationStatus midWeekStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_MID_WEEK.toString());
        MissionHealthNotificationStatus endWeekStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_END_WEEK.toString());

        int retries = 0;
        while(null==dailyStatus && null==midWeekStatus && null==endWeekStatus && retries<300){
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            dailyStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_DAILY.toString());
            midWeekStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_MID_WEEK.toString());
            endWeekStatus = missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_END_WEEK.toString());
            retries++;
        }
        Assert.assertNotNull(dailyStatus);
        Assert.assertEquals(MissionHealthNotificationStatus.PROCESSING, dailyStatus.getStatus());
        dailyStatus.setComplete(true);
        dailyStatus.setStatus(MissionHealthWeeklyStatus.SUCCESS);
        dailyStatus.setCompleteDatetime(new Date());
        missionHealthDataService.missionHealthDataLayer.saveNotificationStatus(dailyStatus);

        Assert.assertNotNull(midWeekStatus);
        Assert.assertEquals(MissionHealthNotificationStatus.PROCESSING, midWeekStatus.getStatus());
        midWeekStatus.setComplete(true);
        midWeekStatus.setStatus(MissionHealthWeeklyStatus.SUCCESS);
        midWeekStatus.setCompleteDatetime(new Date());
        missionHealthDataService.missionHealthDataLayer.saveNotificationStatus(midWeekStatus);

        Assert.assertNotNull(endWeekStatus);
        Assert.assertEquals(MissionHealthNotificationStatus.PROCESSING, endWeekStatus.getStatus());
        endWeekStatus.setComplete(true);
        endWeekStatus.setStatus(MissionHealthWeeklyStatus.SUCCESS);
        endWeekStatus.setCompleteDatetime(new Date());
        missionHealthDataService.missionHealthDataLayer.saveNotificationStatus(endWeekStatus);

        Assert.assertNull(missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_DAILY.toString()));
        Assert.assertNull(missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_MID_WEEK.toString()));
        Assert.assertNull(missionHealthDataService.missionHealthDataLayer.startNotificationTask(NotificationType.EMAIL_REMINDER_TYPE_END_WEEK.toString()));
    }

    @Test
    /* Added this test to more conveniently debug the weekly job - should be ignored by default */
    public void runWeeklyTasksOnce(){
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    @Test
    public void runWeeklyTasksTest(){

        removePatientInfoForWeeklyTasks();
        createPatientInfoForWeeklyTasks();

        simulateWeekOne();
        validateWeekOne();

        simulateWeekTwo();
        validateWeekTwo();

        simulateWeekThree();
        validateWeekThree();
        
        simulateWeekFour();
        validateWeekFour();
        
        simulateWeekFive();
        validateWeekFive();
        
        simulateWeekSix();
        validateWeekSix();
        
        simulateWeekSeven();
        validateWeekSeven();
        
        simulateWeekEight();
        validateWeekEight();
        
        simulateWeekNine();
        simulateWeekTen();
        simulateWeekEleven();
        simulateWeekTwelve();
        
        simulateWeekThirteen();
        validateWeekThirteen();
        
        simulateWeekFourteen();
        
        simulateWeekFiveteen();
        validateWeekFiveteen();
        
        simulateWeekSixteen();
        validateWeekSixteen();
        
        simulateWeekSeventeen();
        simulateWeekEighteen();
        validateWeekEighteen();
        simulateWeekNineteen();
        simulateWeekTwenty();
        validateWeekTwenty();
        simulateWeekTwentyOne();
        simulateWeekTwentyTwo();
        validateWeekTwentyTwo();
        simulateWeekTwentyThree();
        simulateWeekTwentyFour();
        validateWeekTwentyFour();
        simulateWeekTwentyFive();
        simulateWeekTwentySix();
        validateWeekTwentySix();
        simulateWeekTwentySeven();
        simulateWeekTwentyEight();
        validateWeekTwentyEight();
        simulateWeekTwentyNine();
        simulateWeekThirty();
        validateWeekThirty();
        simulateWeekThirtyOne();
        simulateWeekThirtyTwo();
        validateWeekThirtyTwo();
        
        validateFailureHandling();
        validateClearingOldMissions();
    }

    private void validateFailureHandling() {
        try {
            /* load some bad data */
            MongoClient mongoClient = new MongoClient();
            DB db = mongoClient.getDB(missionhealthdb);
            DBCollection dbCollection = db.getCollection(missionhealthdetails);
            DBObject badDataObject = new BasicDBObject("patientId", "badDataPatient")
                    .append("loginDate", "NOT_A_DATE");
            dbCollection.insert(badDataObject);

            missionHealthTaskService.triggerWeeklyTasks();
            missionHealthTaskService.runWeeklyTasks();
            MissionHealthWeeklyStatus status = missionHealthTaskService.missionHealthDataLayer.fetchMostRecentMissionHealthWeeklyStatus();
            Assert.assertNotNull(status);
            Assert.assertFalse(status.isComplete());
            /* must remove the bad data!! */
            dbCollection.remove(badDataObject);
            mongoClient.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    private void validateClearingOldMissions() {
        PatientIdentifier patientWithOldMissionId = new PatientIdentifier("EDIPI", "oldMissionTestPatient");
        missionHealthDataService.removeMissionHealthDetail(missionHealthDataService.getMissionHealthDetail(patientWithOldMissionId));

        saveMissionHealthDetail("oldMissionTestPatient", "oldMissionPatientName");

        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(patientWithOldMissionId);
        MissionHealthProfile profile = new MissionHealthProfile();
        profile.setPatientIdentifier(patientWithOldMissionId);
        profile.setName("oldMissionsPatientName");
        profile.setService(Coast_Guard);
        profile.setReminder("None");
        profile.setEmail("email@address.com");

        missionHealthDataService.saveMissionHealthProfile(profile);

        Mission mission = new Mission();
        mission.setCompetingService(Navy);

        mission = missionHealthDataService.createNewMission(patientWithOldMissionId, mission);
        mission.setStartDate(DateHelper.minusMonths(DateHelper.getOneYearAgo(), 1));
        missionHealthDataService.updateMission(patientWithOldMissionId, mission);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
        mhd = missionHealthDataService.getMissionHealthDetail(patientWithOldMissionId);

        Assert.assertEquals(0, mhd.getMissions().size());
    }

    private void createPatientInfoForWeeklyTasks(){
        MissionHealthDetail lazyMhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        MissionHealthDetail activeMhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        MissionHealthDetail otherMhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);

        MissionHealthProfile profile = new MissionHealthProfile();
        profile.setPatientIdentifier(lazyPatientId);
        profile.setName("LAZY");
        profile.setService(Army);
        profile.setGender("MALE");
        profile.setDateOfBirth(DateHelper.parse("01/01/1980","MM/dd/yyyy"));
        profile.setEmail("lazy@army.gov");
        profile.setReminder("None");
        missionHealthDataService.updateMissionHealthProfile(profile);

        profile = new MissionHealthProfile();
        profile.setPatientIdentifier(activePatientId);
        profile.setName("ACTIVE");
        profile.setService(Marines);
        profile.setGender("MALE");
        profile.setDateOfBirth(DateHelper.parse("01/02/1980","MM/dd/yyyy"));
        profile.setEmail("active@marines.gov");
        profile.setReminder("None");
        missionHealthDataService.updateMissionHealthProfile(profile);

        profile = new MissionHealthProfile();
        profile.setPatientIdentifier(otherPatientId);
        profile.setName("OTHER");
        profile.setService(Air_Force);
        profile.setGender("FEMALE");
        profile.setDateOfBirth(DateHelper.parse("01/03/1980","MM/dd/yyyy"));
        profile.setEmail("active@airForce.gov");
        profile.setReminder("End of Mission");
        missionHealthDataService.updateMissionHealthProfile(profile);
    }

    private void removePatientInfoForWeeklyTasks() {
        MissionHealthDetail lazyMhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        MissionHealthDetail activeMhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        MissionHealthDetail otherMhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        missionHealthDataService.removeMissionHealthDetail(lazyMhd);
        missionHealthDataService.removeMissionHealthDetail(activeMhd);
        missionHealthDataService.removeMissionHealthDetail(otherMhd);
    }

    private void simulateWeeklyLogin(){
        simulateLogin(lazyPatientId, true, true);
        simulateLogin(activePatientId, true, true);
        simulateLogin(otherPatientId, true, true);
    }

    private void simulateLogin(PatientIdentifier patientIdentifier, boolean newDay, boolean newSession){
        if(newDay){
            /* fake new login date by updating login to yesterday */
            MongoClient mongoClient = null;
            try {
                mongoClient = new MongoClient();
                DB db = mongoClient.getDB(missionhealthdb);
                DBCollection dbCollection = db.getCollection(missionhealthdetails);
                String yesterday = DateHelper.formatDate(DateHelper.beginOfDate(DateHelper.getYesterday()));
                DBObject updtLogin = new BasicDBObject("$set", new BasicDBObject("loginDate", yesterday));
                dbCollection.update(new BasicDBObject("patientId", patientIdentifier.getUniqueId()), updtLogin, true, false);
            } catch (UnknownHostException e) {
                e.printStackTrace();
                Assert.assertTrue("Failed to connect to mongo", false);
            }
            MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(patientIdentifier, new Date());
        }else if(newSession){
            MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(patientIdentifier, new Date());
        }else{
            MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(patientIdentifier);
        }

    }

    private void simulateWeekOne(){
        simulateWeeklyLogin();

        generateMissionReadinessReport(lazyPatientId);
    	generateMissionReadinessReport(activePatientId);
    	generateMissionReadinessReport(otherPatientId);
    	
    	createMissionsByPercentageCompleted(Marines,lazyPatientId,0);
        
    	createMissionsByPercentageCompleted(Army,activePatientId,100);
        createCompletedMission(Army,activePatientId);
        
        createAttemptedMission(Army,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekOne(){
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        validateTotalUsers(mhd);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(0);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for incomplete mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertEquals("0 points awarded for 0% progress", 0, mission.getPointsWon());
        Assert.assertEquals("Total points forfeited for 0% progress", mission.getTotalPoints(), mission.getPointsForfeited());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(1), mhd.getTotalAttemptedMissions());
        Assert.assertFalse("Patient: "+lazyPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Rank correctly populated", new Integer(0), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertTrue("Show message flag is set to true", mission.isShowMessage());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        validateTotalUsers(mhd);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 2, mhd.getMissions().size());
        mission = mhd.getMissions().get(0);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertTrue("Show message flag is set to true", mission.isShowMessage());
        mission = mhd.getMissions().get(1);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(2), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(2), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(0), mhd.getTotalAttemptedMissions());
        Assert.assertTrue("Show message flag is set to true", mission.isShowMessage());

        Assert.assertTrue("Patient: "+activePatientId.getUniqueId()+" has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(0), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("New Rank correctly populated", new Integer(1), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(2), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        validateTotalUsers(mhd);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        mission = mhd.getMissions().get(0);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for incomplete mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertTrue("Some points awarded for progress less than threshold", mission.getPointsWon() > 0);
        Assert.assertTrue("Some points forfeited for progress less than threshold", mission.getPointsForfeited() > 0);
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(1), mhd.getTotalAttemptedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Rank correctly populated", new Integer(0), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertTrue("Show message flag is set to true", mission.isShowMessage());
        
        MissionHealthWeeklyStatus status = missionHealthDataService.missionHealthDataLayer.fetchMostRecentMissionHealthWeeklyStatus();
        Assert.assertNotNull("Weekly job created a status record", status);
        Assert.assertTrue("Weekly job completed successfully", status.isComplete());
        Assert.assertTrue("Weekly job reflects that at least 3 users logged in", status.getUsersWithLogin()>=3);
        Assert.assertTrue("Weekly job reflects that there were at least 3 logins", status.getTotalLogins()>=3);
        Assert.assertTrue("Weekly job reflects that at least 2 missions were completed", status.getTotalMissionsCompleted() >= 2);
        Assert.assertNotNull("Weekly job has created service-level metrics", status.getServiceMetrics());
        Assert.assertNotNull("Start Datetime is not null", status.getStartDatetime());
        Assert.assertTrue("Weekly job has created service-level metrics for each service", status.getServiceMetrics().size()>=3 &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Army)) &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Marines)) &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Air_Force)));
        for(WeeklyServiceMetrics metrics : status.getServiceMetrics()){
            Assert.assertNotNull("Service is populated", metrics.getService());
            Assert.assertNotNull("Total completed missions is populated", metrics.getTotalMissionsCompleted());
            Assert.assertNotNull("Total users is populated", metrics.getTotalUsers());
            Assert.assertNotNull("Total active users is populated", metrics.getActiveUsers());
            if(metrics.getService().equals(Marines))
                Assert.assertTrue("Marines has at least 2 completed missions", metrics.getTotalMissionsCompleted()>=2);
        }
        Date statusStartDatetime = status.getStartDatetime();
        List<WeeklyUserMetrics> weeklyUserMetricsList = missionHealthDataService.missionHealthDataLayer.getWeeklyUserMetricsByDate(statusStartDatetime);
        for(WeeklyUserMetrics metrics : weeklyUserMetricsList){
            Assert.assertNotNull("Patient Id populated", metrics.getPatientId());
            if(metrics.getPatientId().equals(lazyPatientId.getUniqueId()) ||
                    metrics.getPatientId().equals(activePatientId.getUniqueId()) ||
                    metrics.getPatientId().equals(otherPatientId.getUniqueId())){
                Assert.assertNotNull("Readiness Reports populated", metrics.getMissionReadinessReportList());
                Assert.assertEquals(new Integer(1), metrics.getDaysWithLoginForCycle());
                Assert.assertTrue("Weekly metrics shows first readiness report", metrics.getMissionReadinessReportList().size() >= 1 );
            }
        }
        Assert.assertTrue("Annual Service Metrics needs to be size of 5 each for one service", status.getAnnualServiceMetrics().size()==5);
        for(WeeklyServiceMetrics metrics : status.getAnnualServiceMetrics()){
            Assert.assertNotNull("Service is populated", metrics.getService());
            Assert.assertNotNull("Total completed missions is populated", metrics.getTotalMissionsCompleted());
            Assert.assertNotNull("Total points is populated", metrics.getTotalPoints());
            Assert.assertNotNull("Total active users is populated", metrics.getActiveUsers());
            Assert.assertNotNull("Total troops is populated", metrics.getTotalTroops());
            if(metrics.getService().equals(Marines))
                Assert.assertTrue("Marines has at least 2 completed missions", metrics.getTotalMissionsCompleted()>=2);
        }
        validateStandings();
    }

    private void simulateWeekTwo() {
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);

        Mission mission = new Mission();
        mission.setName("Run 20 miles 3 times this week");
        mission.setDescription("Run 20 miles 3 times this week in morning");
        mission.setCompetingService(Army);
        mission = missionHealthDataService.createNewMission(activePatientId, mission);
        mission.setPercentageCompleted("100%");
        mission.setTotalPoints(new Integer(80));
        missionHealthDataService.updateMission(activePatientId, mission);

        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,otherPatientId);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekTwo(){
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(1), mhd.getTotalAttemptedMissions());
        Assert.assertFalse("Patient: "+lazyPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Rank correctly populated", new Integer(0), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());

        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 4, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(2);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(3);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(4), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(4), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(0), mhd.getTotalAttemptedMissions());
        
        Assert.assertTrue("Patient: "+activePatientId.getUniqueId()+" has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(1), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("New Rank correctly populated", new Integer(2), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(4), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 2, mhd.getMissions().size());
        mission = mhd.getMissions().get(1);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(2), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(1), mhd.getTotalAttemptedMissions());
        
        Assert.assertTrue("Patient: "+otherPatientId.getUniqueId()+" has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(0), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("New Rank correctly populated", new Integer(1), mhd.getRank().getLevel());
        Assert.assertEquals("Troops correctly populated", new Integer(2), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());

        MissionHealthWeeklyStatus status = missionHealthDataService.missionHealthDataLayer.fetchMostRecentMissionHealthWeeklyStatus();
        Assert.assertNotNull("Weekly job created a status record", status);
        Assert.assertTrue("Weekly job completed successfully", status.isComplete());
        Assert.assertTrue("Weekly job reflects that at least 3 users logged in", status.getUsersWithLogin()>=3);
        Assert.assertTrue("Weekly job reflects that there were at least 3 logins", status.getTotalLogins()>=3);
        Assert.assertTrue("Weekly job reflects that at least 2 missions were completed", status.getTotalMissionsCompleted() >= 3);
        Assert.assertNotNull("Weekly job has created service-level metrics", status.getServiceMetrics());
        Assert.assertTrue("Weekly job has created service-level metrics for each service", status.getServiceMetrics().size()>=3 &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Army)) &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Marines)) &&
                                                                                           status.getServiceMetrics().contains(new WeeklyServiceMetrics(Air_Force)));
        for(WeeklyServiceMetrics metrics : status.getServiceMetrics()){
            Assert.assertNotNull("Service is populated", metrics.getService());
            Assert.assertNotNull("Total completed missions is populated", metrics.getTotalMissionsCompleted());
            Assert.assertNotNull("Total users is populated", metrics.getTotalUsers());
            Assert.assertNotNull("Total active users is populated", metrics.getActiveUsers());
            if(metrics.getService().equals(Marines))
                Assert.assertTrue("Marines has at least 4 completed missions", metrics.getTotalMissionsCompleted()>=4);
            if(metrics.getService().equals(Air_Force))
                Assert.assertTrue("Air Force has at least 1 completed missions", metrics.getTotalMissionsCompleted()>=1);
        }
        Date statusStartDatetime = status.getStartDatetime();
        List<WeeklyUserMetrics> weeklyUserMetricsList = missionHealthDataService.missionHealthDataLayer.getWeeklyUserMetricsByDate(statusStartDatetime);
        for(WeeklyUserMetrics metrics : weeklyUserMetricsList){
            Assert.assertNotNull("Patient Id populated", metrics.getPatientId());
            if(metrics.getPatientId().equals(lazyPatientId.getUniqueId()) ||
                    metrics.getPatientId().equals(activePatientId.getUniqueId()) ||
                    metrics.getPatientId().equals(otherPatientId.getUniqueId())){
                Assert.assertNotNull("Readiness Reports populated", metrics.getMissionReadinessReportList());
                Assert.assertEquals(new Integer(1), metrics.getDaysWithLoginForCycle());
                Assert.assertTrue("Weekly metrics shows first readiness report", metrics.getMissionReadinessReportList().size() >= 1 );
            }
        }
        Assert.assertTrue("Annual Service Metrics needs to be size of 5 each for one service", status.getAnnualServiceMetrics().size()==5);
        for(WeeklyServiceMetrics metrics : status.getAnnualServiceMetrics()){
            Assert.assertNotNull("Service is populated", metrics.getService());
            Assert.assertNotNull("Total completed missions is populated", metrics.getTotalMissionsCompleted());
            Assert.assertNotNull("Total points is populated", metrics.getTotalPoints());
            Assert.assertNotNull("Total active users is populated", metrics.getActiveUsers());
            Assert.assertNotNull("Total troops is populated", metrics.getTotalTroops());
            if(metrics.getService().equals(Marines))
                Assert.assertTrue("Marines has at least 4 completed missions", metrics.getTotalMissionsCompleted()>=4);
            if(metrics.getService().equals(Air_Force))
                Assert.assertTrue("Air Force has at least 1 completed missions", metrics.getTotalMissionsCompleted()>=1);
        }
        validateStandings();
    }

    private void simulateWeekThree(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);

        createCompletedMission(Army,activePatientId);
        createCompletedMission(Navy,activePatientId);
        createAttemptedMission(Army,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekThree(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(1), mhd.getTotalAttemptedMissions());
        Assert.assertFalse("Patient: " + lazyPatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 6, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(4);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(5);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(6), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(6), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(0), mhd.getTotalAttemptedMissions());
        
        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(1), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Pending Rank correctly populated", new Integer(3), mhd.getPendingRank().getLevel());
        Assert.assertEquals("Next Rank correctly populated", new Integer(2), mhd.getRank().getLevel());
        Assert.assertNotNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated=" + mhd.getTroops(), true, mhd.getTroops() == 4 || mhd.getTroops() == 6);
        Assert.assertEquals("Mission Failure counter", new Integer(0), mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 3, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(3), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Attempted missions correctly updated", new Integer(2), mhd.getTotalAttemptedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(2), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(1),mhd.getFailedMissionCounter());

        validateStandings();
    }
    
    private void simulateWeekFour(){
        simulateWeeklyLogin();

        generateMissionReadinessReport(activePatientId);
    	
    	missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        Mission mission = new Mission();
        mission.setName("Run 30 miles 3 times this week");
        mission.setDescription("Run 30 miles 3 times this week in morning");
        mission.setCompetingService(Army);
        mission = missionHealthDataService.createNewMission(activePatientId, mission);
        mission.setPercentageCompleted("100%");
        mission.setTotalPoints(new Integer(60));
        missionHealthDataService.updateMission(activePatientId, mission);

        createCompletedMission(Army,activePatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekFour(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: " + lazyPatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter", new Integer(0), mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 8, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(6);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(7);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(8), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(8), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(3), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("New Rank correctly populated", new Integer(4), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated="+mhd.getTroops(), true, mhd.getTroops()==6 || mhd.getTroops()==8);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 3, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(3), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(2), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(1),mhd.getFailedMissionCounter());

        validateStandings();
    }
    
    private void simulateWeekFive(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createAttemptedMission(Navy,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekFive(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: " + lazyPatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter", new Integer(0), mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 10, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(8);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(9);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(10), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(10), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(3), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("New Rank correctly populated", new Integer(4), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated="+mhd.getTroops(), true, mhd.getTroops()==6 || mhd.getTroops()==8 || mhd.getTroops()==9 || mhd.getTroops()==11);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertEquals("Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 4, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(4), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(2), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(2),mhd.getFailedMissionCounter());

    }
    
    private void simulateWeekSix(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createAttemptedMission(Army,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekSix(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: " + lazyPatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter", new Integer(0), mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 12, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(10);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(11);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(12), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(12), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(4), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(5), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated=" + mhd.getTroops(), true, mhd.getTroops() >= 6);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 5, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(5), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(1), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(3),mhd.getFailedMissionCounter());

    }
    
    private void simulateWeekSeven(){
        simulateWeeklyLogin();

        generateMissionReadinessReport(activePatientId);
    	
    	missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createAttemptedMission(Army,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekSeven(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+lazyPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 15, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(12);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(13);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(14);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(15), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(15), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(4), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(5), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated="+mhd.getTroops(), true, mhd.getTroops()>=6);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 6, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(6), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(1), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(1), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(4),mhd.getFailedMissionCounter());

    }
    
    private void simulateWeekEight(){
        simulateWeeklyLogin();

    	missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,otherPatientId);

        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekEight(){
    	MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+lazyPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 17, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(15);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for 100% progress", mission.getTotalPoints(), mission.getPointsWon());
        mission = mhd.getMissions().get(16);
        Assert.assertEquals("Status updated to 'COMPLETE' for complete mission", MissionStatus.COMPLETE, mission.getStatus());
        Assert.assertEquals("Total points awarded for greater than threshold progress", mission.getTotalPoints(), mission.getPointsWon());
        Assert.assertEquals("Total missions correctly updated", new Integer(17), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(17), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(4), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Pending Rank correctly populated", new Integer(6), mhd.getPendingRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(5), mhd.getRank().getLevel());
        Assert.assertNotNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated="+mhd.getTroops(), true, mhd.getTroops()>=6);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 7, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(7), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(2), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(0), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(1), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated:"+mhd.getTroops(), true,mhd.getTroops()==1 || mhd.getTroops()==3);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());

    }
    
    private void simulateWeekNine(){
        simulateWeeklyLogin();
        
        generateMissionReadinessReport(activePatientId);
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Navy,otherPatientId);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekTen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekEleven(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekTwelve(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        createCompletedMission(Army,activePatientId);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekThirteen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
    	
        MissionHealthDetail mhd=missionHealthDataService.getMissionHealthDetail(activePatientId);
        mhd.setTroops(new Integer(20));
        mhd.setAnnualTotalTroops(new Integer(20));
    	missionHealthDataService.updateMissionHealthDetail(mhd);
    	
    	createMissionsByPercentageCompleted(Army,activePatientId,10);
    	createMissionsByPercentageCompleted(Army,activePatientId,20);
        
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }

    private void validateWeekThirteen(){
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(lazyPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 1, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(1), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(0), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+lazyPatientId.getUniqueId()+" has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Troops correctly populated", new Integer(0), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        
        mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 31, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(29);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for not completed mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertEquals("Competing troop not zero", new Integer(1), mission.getTroopsForfeited());
        mission = mhd.getMissions().get(30);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for not completed mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertEquals("Competing troop not zero", new Integer(1), mission.getTroopsForfeited());
        Assert.assertEquals("Total missions correctly updated", new Integer(31), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(29), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(7), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(8), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated=" + mhd.getTroops(), new Integer(18), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(1),mhd.getFailedMissionCounter());
        Assert.assertEquals("Check lost troops show message status", true,mhd.isLostTroopsShowMessage());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
        
        mhd = missionHealthDataService.getMissionHealthDetail(otherPatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 8, mhd.getMissions().size());
        Assert.assertEquals("Total missions correctly updated", new Integer(8), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(3), mhd.getTotalCompletedMissions());
        Assert.assertFalse("Patient: "+otherPatientId.getUniqueId()+" has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(1), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(2), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated:"+mhd.getTroops(), true,mhd.getTroops()==1 || mhd.getTroops()==3);
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());

    }
    
    private void simulateWeekFourteen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        
    	createMissionsByPercentageCompleted(Army,activePatientId,10);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekFiveteen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        
    	createMissionsByPercentageCompleted(Army,activePatientId,10);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekFiveteen(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 33, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(32);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for not completed mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertEquals("Competing troop not zero", new Integer(1), mission.getTroopsForfeited());
        
        Assert.assertEquals("Total missions correctly updated", new Integer(33), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(29), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(7), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(8), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated=" + mhd.getTroops(), new Integer(14), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(3),mhd.getFailedMissionCounter());
        Assert.assertEquals("Check lost troops show message status", true,mhd.isLostTroopsShowMessage());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
    }
    private void simulateWeekSixteen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        missionHealthDataService.savePromotedStatus(otherPatientId);
        
    	createMissionsByPercentageCompleted(Army,activePatientId,10);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekSixteen(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Past missions populated", 34, mhd.getMissions().size());
        Mission mission = mhd.getMissions().get(33);
        Assert.assertEquals("Status updated to 'ATTEMPTED' for not completed mission", MissionStatus.ATTEMPTED, mission.getStatus());
        Assert.assertEquals("Competing troop not zero", new Integer(1), mission.getTroopsForfeited());
        
        Assert.assertEquals("Total missions correctly updated", new Integer(34), mhd.getTotalMissions());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(29), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(7), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(8), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Troops correctly populated=" + mhd.getTroops(), new Integer(12), mhd.getTroops());
        Assert.assertEquals("Mission Failure counter",new Integer(4),mhd.getFailedMissionCounter());
        Assert.assertEquals("Check lost troops show message status", true,mhd.isLostTroopsShowMessage());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
    }
    
    private void simulateWeekSeventeen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekEighteen(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void validateWeekEighteen(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(35), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(7), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(8), mhd.getRank().getLevel());
        Assert.assertEquals("Pending Rank correctly populated", new Integer(9), mhd.getPendingRank().getLevel());
    }
    
    private void simulateWeekNineteen(){
        simulateWeeklyLogin();
        
        generateMissionReadinessReport(activePatientId);
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekTwenty(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekTwenty(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(41), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(9), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(10), mhd.getRank().getLevel());
    }

    private void simulateWeekTwentyOne(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekTwentyTwo(){
        simulateWeeklyLogin();

        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void validateWeekTwentyTwo(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(47), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(10), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(11), mhd.getRank().getLevel());
    }
    private void simulateWeekTwentyThree(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekTwentyFour(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekTwentyFour(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(53), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(10), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(11), mhd.getRank().getLevel());
        Assert.assertEquals("Pending Rank correctly populated", new Integer(12), mhd.getPendingRank().getLevel());
    }
    
    private void simulateWeekTwentyFive(){
        simulateWeeklyLogin();
        
        generateMissionReadinessReport(activePatientId);
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekTwentySix(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void validateWeekTwentySix(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(59), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(12), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(13), mhd.getRank().getLevel());
    }
    
    private void simulateWeekTwentySeven(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekTwentyEight(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekTwentyEight(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(65), mhd.getTotalCompletedMissions());

        Assert.assertTrue("Patient: " + activePatientId.getUniqueId() + " has been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(13), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(14), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
    }
    
    private void simulateWeekTwentyNine(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void simulateWeekThirty(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekThirty(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(71), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(13), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(14), mhd.getRank().getLevel());
        Assert.assertEquals("Pending Rank correctly populated", new Integer(15), mhd.getPendingRank().getLevel());
        Assert.assertNotNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
    }
    private void simulateWeekThirtyOne(){
        simulateWeeklyLogin();
        
        generateMissionReadinessReport(activePatientId);
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    private void simulateWeekThirtyTwo(){
        simulateWeeklyLogin();
        
        missionHealthDataService.savePromotedStatus(activePatientId);
        
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    	createCompletedMission(Army,activePatientId);
    
        missionHealthTaskService.triggerWeeklyTasks();
        missionHealthTaskService.runWeeklyTasks();
    }
    
    private void validateWeekThirtyTwo(){
        
        MissionHealthDetail mhd = missionHealthDataService.getMissionHealthDetail(activePatientId);
        Assert.assertEquals("Current missions are cleared", 0, mhd.getCurrentMissions().size());
        Assert.assertEquals("Total completed missions correctly updated", new Integer(77), mhd.getTotalCompletedMissions());

        Assert.assertFalse("Patient: " + activePatientId.getUniqueId() + " has not been promoted", mhd.isPromoted());
        Assert.assertEquals("Previous Rank correctly populated", new Integer(14), mhd.getPreviousRank().getLevel());
        Assert.assertEquals("Rank correctly populated", new Integer(15), mhd.getRank().getLevel());
        Assert.assertNull("Pending Rank populated", mhd.getPendingRank());
        Assert.assertEquals("Mission Failure counter",new Integer(0),mhd.getFailedMissionCounter());
        Assert.assertEquals("Total Annual Points",mhd.getAnnualTotalPoints(),mhd.getPoints());
        Assert.assertEquals("Total Annual Completed Missions",mhd.getAnnualTotalCompletedMissions(),mhd.getTotalCompletedMissions());
        Assert.assertEquals("Total Annual Troops",mhd.getAnnualTotalTroops(),mhd.getTroops());
    }
    
    private void saveMissionHealthDetail(String patientId, String name) {

        MissionHealthDetail missionHealthDetail = new MissionHealthDetail();
        missionHealthDetail.setPatientId(patientId);
        missionHealthDetail.setMissionHealthProfile(generateMissionHealthProfile(patientId, name));
        missionHealthDetail.setLoginDate(new Date());
        missionHealthDetail.setPoints(0);
        missionHealthDetail.setRank(new MissionHealthRank(1));
        missionHealthDetail.setTroops(2);

        missionHealthDataService.updateMissionHealthDetail(missionHealthDetail);
    }

    private MissionHealthProfile generateMissionHealthProfile(String patientId, String name) {
        MissionHealthProfile missionHealthProfile = new MissionHealthProfile();
        missionHealthProfile.setPatientId(patientId);
        missionHealthProfile.setName(name);
        missionHealthProfile.setDateOfBirth(DateHelper.parseDate("08/08/1984"));
        missionHealthProfile.setGender("M");
        missionHealthProfile.setReminder("Weekly");
        missionHealthProfile.setEmail(name+"@agilexhealth.com");
        missionHealthProfile.setService("Navy");

        return missionHealthProfile;
    }

    private MissionHealthDetail generateMissionReadinessReport(PatientIdentifier patientIdentifier){
        MissionReadinessReport mrr=new MissionReadinessReport();
        mrr.setEmotional(5);
        mrr.setHealth(10);
        mrr.setPhysical(15);
        mrr.setInsDate(DateHelper.getYesterday());
        return missionHealthDataService.insertMissionReadinessReport(patientIdentifier,mrr);
    }

    private void validateStandings(){
        List<MissionHealthDetail> allDetails = missionHealthDataService.missionHealthDataLayer.getAllMissionHealthDetails();
        Collections.sort(allDetails, new MissionHealthDetailStandingComparator());
        Integer points = null;
        Integer standing = null;
        for(MissionHealthDetail mhd : allDetails){
            Assert.assertNotNull(mhd.getStanding());
            Assert.assertNotNull(mhd.getPoints());
            if(null != points && null != standing){
                Assert.assertTrue(mhd.getStanding()>=standing);
                if(mhd.getStanding().equals(standing))
                    Assert.assertTrue(mhd.getPoints().equals(points));
                else
                    Assert.assertTrue(mhd.getPoints()<points);
            }
            points = mhd.getPoints();
            standing = mhd.getStanding();
        }
    }

    private void validateTotalUsers(MissionHealthDetail missionHealthDetail){
        Assert.assertNotNull(missionHealthDetail.getTotalUsers());
        List<MissionHealthDetail> allDetails = missionHealthDataService.missionHealthDataLayer.getAllMissionHealthDetails();
        Assert.assertEquals(missionHealthDetail.getTotalUsers(), Integer.valueOf(allDetails.size()));
    }
    
    @Test
    public void getAnnualServiceComparisonRollUp(){
    	AnnualServiceRollUp annualServiceRollUp=missionHealthDataService.getAnnualServiceComparisonRollUp();
    	Assert.assertNotNull("AnnualServiceRollUp not null", annualServiceRollUp);
    }
    
    private void createCompletedMission(String service, PatientIdentifier patient){
    	Mission mission = new Mission();
        mission.setName("Run 30 miles 3 times this week");
        mission.setDescription("Run 30 miles 3 times this week in morning");
        mission.setCompetingService(service);
        mission = missionHealthDataService.createNewMission(patient, mission);
        int completeThresh = Integer.parseInt(mission.getThresholdPercentage().replace("%", ""));
        mission.setPercentageCompleted(Integer.toString(completeThresh+1)+"%");
        missionHealthDataService.updateMission(patient, mission);
    }
    
    private void createAttemptedMission(String service, PatientIdentifier patient){
    	Mission mission = new Mission();
        mission.setName("Run 10 miles 3 times this week");
        mission.setDescription("Run 10 miles 3 times this week in morning");
        mission.setCompetingService(service);
        mission = missionHealthDataService.createNewMission(patient, mission);
        int completeThresh = Integer.parseInt(mission.getThresholdPercentage().replace("%", ""));
        mission.setPercentageCompleted(Integer.toString(completeThresh-1)+"%");
        missionHealthDataService.updateMission(patient, mission);
    }
    
    private void createMissionsByPercentageCompleted(String service, PatientIdentifier patient,int percentageCompleted){
    	Mission mission = new Mission();
        mission.setName("Run 10 miles 3 times this week");
        mission.setDescription("Run 10 miles 3 times this week in morning");
        mission.setCompetingService(service);
        mission = missionHealthDataService.createNewMission(patient, mission);
        mission.setPercentageCompleted(Integer.toString(percentageCompleted)+"%");
        missionHealthDataService.updateMission(patient, mission);
    }
    
    @Ignore
    @Test
    public void validateGetMissionYearTimeFrame(){
    	Map<String,Calendar> missionYearTimeFrame=MissionHealthTimeFrameService.getMissionYearTimeFrame(DateHelper.parseDateTime("12/11/2013 00:00:00"));
    	Assert.assertEquals("Start Date", "05/20/2013", DateHelper.formatDate(missionYearTimeFrame.get("startDate").getTime()));
    	Assert.assertEquals("end Date", "05/18/2014", DateHelper.formatDate(missionYearTimeFrame.get("endDate").getTime()));
    	missionYearTimeFrame=MissionHealthTimeFrameService.getMissionYearTimeFrame(DateHelper.parseDateTime("01/01/2013 00:00:00"));
    	Assert.assertEquals("Start Date", "05/21/2012", DateHelper.formatDate(missionYearTimeFrame.get("startDate").getTime()));
    	Assert.assertEquals("end Date", "05/19/2013", DateHelper.formatDate(missionYearTimeFrame.get("endDate").getTime()));
    }
    
}
