/**
@file
@SYMTestCaseID				SYSLIB-SCHSVR-CT-0249
@SYMTestCaseDesc 			OOM test for time-based schedules - UTC
@SYMTestPriority 			High
@SYMTestActions  			OOM test for time-based schedules
@SYMTestExpectedResults		The test must not fail.
@SYMPREQ					PREQ234
*/
static void DoTest1L()
// Time based API's
	{
	
	TInt err = KErrNone;
	TInt tryCount = 0;
	
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0249 ===== Starting OOM test ===== "));
	
	CSchEntryInfoArray* scheduleArray = CreateScheduleArrayLC();
	TSchedulerItemRef ref1;

	TheTest.Next(_L("===== Testing create persistent schedule ====="));
	for (tryCount = 0; ;++tryCount)
		{
		// These allocations are ignored because they cause corruptness
		// of the persistent store.  Its a bit rubbish.
		if(tryCount < 7 || tryCount >8 )
			{
			TheScheduler.__DbgFailNext(tryCount);
			TheScheduler.__DbgMarkHeap();
			err = TheScheduler.CreatePersistentSchedule(ref1, *scheduleArray);
			if (err==KErrNone)
				{
				TheScheduler.__DbgResetHeap();
				break;
				}
			TEST2(err, KErrNoMemory);		
			// reset server side heap for next iteration.
			TheScheduler.__DbgMarkEnd(0);			
			}
		}
	// Check schedule count
	TInt scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 

	// OK, now we have a persistent schedule
	TheTest.Next(_L("===== Testing disable schedule ====="));
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.DisableSchedule(ref1.iHandle);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 

	TheTest.Next(_L("===== Testing enable schedule ====="));
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.EnableSchedule(ref1.iHandle);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 

	TheTest.Next(_L("===== Testing edit schedule ====="));
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		// Even though we use the same array as before, the task scheduler
		// code is not smart enough to just return but actually replaces
		// the existing one, hence we are actually testing this method fully.
		err = TheScheduler.EditSchedule(ref1.iHandle, *scheduleArray);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 

	TheTest.Next(_L("===== Testing delete schedule ====="));
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.DeleteSchedule(ref1.iHandle);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 0); 

	// delete old files.
	// We need to do this because we have actually corrupted the store, 
	// even though its empty.  Without deleting it we get problems below.
	// This is a bit rubbish having to do this but what else can be done??
	TheTest.Next(_L("Delete old files"));
	SchSvrHelpers::DeleteScheduleFilesL();
	
	// OK now add back schedule in preparation for adding tasks.
	err = TheScheduler.CreatePersistentSchedule(ref1, *scheduleArray);
	TEST2(err, KErrNone);

	TheTest.Next(_L("===== Testing ScheduleTask ====="));
	
	_LIT(KTaskName, "TheTaskName");
	TName name = KTaskName();
	TTaskInfo taskInfo(0, name, 2, 0);

	HBufC* data = _L("the data").AllocLC();
	// cant test ScheduleTask API using OOM loop as it does dodgy things to 
	// the store which cause allocation problems.  Need to investigate this 
	// later at some stage.
	TEST2(TheScheduler.ScheduleTask(taskInfo, *data, ref1.iHandle), KErrNone);
	
	// Check schedule and task count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 
	TInt taskCount = CountTasksL(ref1.iHandle);
	TEST(taskCount = 1);	

	TheTest.Next(_L("===== Testing GetScheduleRefsL ====="));

	CSchItemRefArray* refs = new (ELeave) CSchItemRefArray(3);
	CleanupStack::PushL(refs);
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetScheduleRefsL(*refs, EPendingSchedules);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule and task count
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 
	taskCount = CountTasksL(ref1.iHandle);
	TEST(taskCount = 1);	

	TheTest.Next(_L("===== Testing GetScheduleL ====="));

	CTaskInfoArray* tasks = new (ELeave) CTaskInfoArray(3);
	CleanupStack::PushL(tasks);
	TScheduleState2 state;
	TTsTime time;
	CSchEntryInfoArray* entryList = new (ELeave) CSchEntryInfoArray(3);
	CleanupStack::PushL(entryList);
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetScheduleL(ref1.iHandle,
										state,
										*entryList,
										*tasks, time);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	// Check schedule and task count
	TEST(entryList->Count() == 1);
	TEST(tasks->Count() == 1);
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 
	taskCount = CountTasksL(ref1.iHandle);
	TEST(taskCount = 1);	

	CleanupStack::PopAndDestroy(entryList);
	CleanupStack::PopAndDestroy(tasks);

	TheTest.Next(_L("===== Testing GetTaskRefsL ====="));

	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetTaskRefsL(*refs,
										EAllSchedules,
										EAllTasks);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	CleanupStack::PopAndDestroy(refs);

	TheTest.Next(_L("===== Testing GetTaskDataSize ====="));

	TInt size;
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetTaskDataSize(ref1.iHandle,
										size);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}

	TheTest.Next(_L("===== Testing GetTaskInfoL ====="));

	HBufC* newData = HBufC::NewLC(size);
	TPtr pTaskData = newData->Des();

	TTaskInfo newTaskInfo;
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetTaskInfoL(taskInfo.iTaskId,
										newTaskInfo,
										pTaskData,
										ref1,
										time);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	TEST(newData->MatchF(*data) == 0);
	
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 
	taskCount = CountTasksL(ref1.iHandle);
	TEST(taskCount = 1);	

	CleanupStack::PopAndDestroy(newData);
	CleanupStack::PopAndDestroy(data);

	TheTest.Next(_L("===== Testing GetScheduleTypeL ====="));

	TScheduleType type;
	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.GetScheduleTypeL(ref1.iHandle, type);
		if (err==KErrNone)
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	TEST(type == ETimeSchedule);

	CleanupStack::PopAndDestroy(scheduleArray);

	TheTest.Next(_L("===== Testing DeleteTask ====="));

	for (tryCount = 0; ;++tryCount)
		{
		TheScheduler.__DbgFailNext(tryCount);
		TheScheduler.__DbgMarkHeap();
		err = TheScheduler.DeleteTask(taskInfo.iTaskId);
		//include test for KErrNotFound here as task is actually deleted and
		// then store is updated (which causes mem failure).  Problems
		// will still occur if you add a new task again and try and access store
		// as store is likely to still be corrupt. Investigate this??
		if (err==KErrNone || err==KErrNotFound) 
			{
			TheScheduler.__DbgResetHeap();
			break;
			}
		TEST2(err, KErrNoMemory);		
		// reset server side heap for next iteration.
		TheScheduler.__DbgMarkEnd(0);
		}
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 1); 
	taskCount = CountTasksL(ref1.iHandle);
	TEST(taskCount == 0);
	
	//Now delete schedule to setup for next test
	TEST2(TheScheduler.DeleteSchedule(ref1.iHandle), KErrNone);
	scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
	TEST(scheduleCount == 0); 

	SchSvrHelpers::Pause(TheTest);
	}