BEGIN_TOOLBOX_NAMESPACE
USING_TOOLBOX_NAMESPACE


//--------------------------------------------------------------------------------------------------


static
void _GetRFC1123DateString (const XBOX::VTime& inDate, XBOX::VString& outString)
{
	sWORD year, month, day, hour, minute, second, millisecond;
	inDate.GetUTCTime (year, month, day, hour, minute, second, millisecond);

	outString.Clear();

	switch (inDate.GetWeekDay())
	{
	case 0:		outString.AppendCString ("Sun");	break;
	case 1:		outString.AppendCString ("Mon");	break;
	case 2:		outString.AppendCString ("Tue");	break;
	case 3:		outString.AppendCString ("Wed");	break;
	case 4:		outString.AppendCString ("Thu");	break;
	case 5:		outString.AppendCString ("Fri");	break;
	case 6:		outString.AppendCString ("Sat");	break;
	}

	outString.AppendPrintf (", %02d-", day);

	switch (month)
	{
	case 1:		outString.AppendCString ("Jan");	break;
	case 2:		outString.AppendCString ("Feb");	break;
	case 3:		outString.AppendCString ("Mar");	break;
	case 4:		outString.AppendCString ("Apr");	break;
	case 5:		outString.AppendCString ("May");	break;
	case 6:		outString.AppendCString ("Jun");	break;
	case 7:		outString.AppendCString ("Jul");	break;
	case 8:		outString.AppendCString ("Aug");	break;
	case 9:		outString.AppendCString ("Sep");	break;
	case 10:	outString.AppendCString ("Oct");	break;
	case 11:	outString.AppendCString ("Nov");	break;
	case 12:	outString.AppendCString ("Dec");	break;
	}

	outString.AppendPrintf ("-%04d %02d:%02d:%02d GMT", year, hour, minute, second);
}
void VHTTPServerLog::_CalculateNextFileRotationTime()
{
	fNextFileRotationTime.Clear();

	if (fBackupSettings.RotateOnSchedule())
	{
		XBOX::VTime		curTime;
		XBOX::VDuration tempDuration;
		XBOX::VFilePath logPath;

		_GetLogFilePath (logPath);
		fNextFileRotationTime.FromSystemTime();
		curTime.FromSystemTime();

		if (GetFileCreationTime (logPath, &fLastFileRotationTime) != XBOX::VE_OK)
		{
			fLastFileRotationTime.FromSystemTime();
			fLastFileRotationTime.AddDays (-1);
		}

		switch (fBackupSettings.GetLogRotationMode())
		{
			case LRC_NO_ROTATION:
			case LRC_ROTATE_ON_FILE_SIZE:
				fNextFileRotationTime.Clear();
				break;
				
			case LRC_ROTATE_EVERY_HOUR:
			{				
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;	
				
				
				// if the date (dd/mm/yy) is different from the curent date, we have to backup to the current date
				if ((fNextFileRotationTime.GetLocalDay()!=curTime.GetLocalDay())||(fNextFileRotationTime.GetLocalMonth()!=curTime.GetLocalMonth())||(fNextFileRotationTime.GetLocalYear()!=curTime.GetLocalYear()))
				{
					// we use the date of today 
					fNextFileRotationTime.FromSystemTime();	
				}
				
				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());

				while(fNextFileRotationTime <= fLastFileRotationTime)
				{
					fNextFileRotationTime.AddHours( fBackupSettings.GetFrequency());
				}
				
				if ((fNextFileRotationTime.GetLocalDay()!=curTime.GetLocalDay())||(fNextFileRotationTime.GetLocalMonth()!=curTime.GetLocalMonth())||(fNextFileRotationTime.GetLocalYear()!=curTime.GetLocalYear()))
				{
					// set the time to the "starting at" value
					SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());
				}
				break;	// LRC_ROTATE_EVERY_HOUR
			}

			case LRC_ROTATE_EVERY_DAY:
			{
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;
				fNextFileRotationTime.AddDays (fBackupSettings.GetFrequency());

				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());

				break;	// LRC_ROTATE_EVERY_DAY
			}
				
			case LRC_ROTATE_EVERY_WEEK:
			{
				sLONG dayHour = 0;
				//	First, we check if there is a backup today
				//	Then if there is one this week				
				
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;	
				// if the date is the date of today, we just update the hour
				if ((fNextFileRotationTime.GetLocalDay()==curTime.GetLocalDay())&&(fNextFileRotationTime.GetLocalMonth()==curTime.GetLocalMonth())&&(fNextFileRotationTime.GetLocalYear()==curTime.GetLocalYear()))
				{
					VHTTPServerLogBackupSettings::EWeekDay weekDay = (VHTTPServerLogBackupSettings::EWeekDay)curTime.GetWeekDay();

					if (fBackupSettings.GetSaveOnWeekDay (weekDay))
					{	
						dayHour = fBackupSettings.GetWeekDayBackupHour (weekDay);
						
						SetTimeValue (fNextFileRotationTime, dayHour);
					}

					if (fLastFileRotationTime < fNextFileRotationTime)
					{
						break;	// we will have to backup later this day
					}
				}
				// no backup time has been determined
				// let's search the next day which has a backup planned
				
				bool flagIsOk = false;
				fNextFileRotationTime = fLastFileRotationTime;	
				//	This week a backup is planned... because a backup has been done already
				//	Let's check if another backup is planned this week
				//	note : like in the database backup, if we missed one backup, it will be done ASAP
				if (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eSunday)
				{
					while (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eSunday  && !flagIsOk)
					{
						VHTTPServerLogBackupSettings::EWeekDay weekDay = (VHTTPServerLogBackupSettings::EWeekDay)fNextFileRotationTime.GetWeekDay();

						fNextFileRotationTime.AddDays (1);		// check the next day

						if (fBackupSettings.GetSaveOnWeekDay (weekDay))
						{
							dayHour = fBackupSettings.GetWeekDayBackupHour (weekDay);
							
							SetTimeValue (fNextFileRotationTime, dayHour);
							flagIsOk = true;
						}
					}
				}

				if (flagIsOk)	// another backup has been planned
					break;
				
				//	There is no backup to do this week
				//	Let's look gEveryWeek after ...
				fNextFileRotationTime = fLastFileRotationTime;	
				fNextFileRotationTime.AddDays (fBackupSettings.GetFrequency() * 7);

				//	We "rewind" the week until the first day of the week : Monday !
				while (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eMonday)
					fNextFileRotationTime.AddDays(-1);

				//	We look each day of the week
				if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eMonday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eMonday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eTuesday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eTuesday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(1);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eWednesday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eWednesday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(2);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eThursday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eThursday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(3);
					
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eFriday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eFriday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(4);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eSaturday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eSaturday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(5);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eSunday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eSunday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(6);
				}

				break; // LRC_ROTATE_EVERY_WEEK
			}

			case LRC_ROTATE_EVERY_MONTH:
			{	
				fNextFileRotationTime = fLastFileRotationTime;
				fNextFileRotationTime.AddMonths( fBackupSettings.GetFrequency());
				
				if (fBackupSettings.GetMonthDay() == 29)	// the preference selected is "Last"
				{
					fNextFileRotationTime.AddMonths(1);
					fNextFileRotationTime.SetLocalDay(1);	// sets the time to the first day of he month
					fNextFileRotationTime.AddDays(-1);		// removes one day to get the last day of the previous month
				}
				else
				{
					fNextFileRotationTime.SetLocalDay(fBackupSettings.GetMonthDay());
				}
				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetMonthDayHour());

				break;	// LRC_ROTATE_EVERY_MONTH
			}
				
			default : // Trying to backup on an unknown schedule
				assert (false);
				break;
		}
	}
}