/**
 * OnDayEveryNWeeks.java
 * Created on Jul 10, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.job.timers;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.tandbergtv.watchpoint.pmm.entities.RuleParameter;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameterDataType;
import com.tandbergtv.watchpoint.pmm.entities.RuleTypeParameter;
import com.tandbergtv.watchpoint.pmm.job.util.Day;

/**
 * This class gets the closest day specified in the rule parameters from
 * the given start date and then returns the time for 'N" weeks from that
 * date onwards. It uses 'EveryNWeeks' timer to get the second half.
 * 
 * @author spuranik
 *
 */
public class OnDayEveryNWeeks implements ITimeRepresentation {

	private static final Logger logger = Logger.getLogger(OnDayEveryNWeeks.class);
	public static String DATE_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.job.timers.ITimeRepresentation#getTime(java.util.List, java.util.List, java.util.Date)
	 */
	public Object getTime(List<RuleTypeParameter> ruleTypeParams, List<RuleParameter> params,
			Date startDate) {

		String day = TimerHelper.getParameter(ruleTypeParams, params, RuleParameterDataType.DAY);

		logger.debug("Initial job start date: " + startDate);
		Date jobStartDate = getClosestDay(startDate, day);
		logger.debug("Setting job start date to: " + jobStartDate.toString());

		EveryNWeeks weeklyTimer = new EveryNWeeks();
		return weeklyTimer.getTime(ruleTypeParams, params, jobStartDate);
	}

	/**
	 * Adds days to get to the closest day specified from the start date
	 * e.g. startdate = 2008-07-10 which is a THURSDAY
	 * day = MONDAY
	 * So this will return 2008-07-14 which is a MONDAY  
	 * 
	 * @param startDate
	 * 	start date from which the closest 'DAY' should be computed 
	 * @param day
	 * 	SUNDAY - SATURDAY. 
	 * @return
	 */
	private Date getClosestDay(Date startDate, String day) {
		Calendar c = Calendar.getInstance();
		c.setTime(startDate);
		int startDay = c.get(Calendar.DAY_OF_WEEK);
		// ordinal is zero based		
		int d = Day.valueOf(day).ordinal() + 1;

		// if startDate is on the same day as the requested day, return startDate.
		if (startDay == d) {
			return startDate;
		}

		// else proceed to compute the date for the next closest future day
		int daysLeftInWeek = Calendar.SATURDAY - startDay;
		int daysToAdd = daysLeftInWeek + d;
		c.add(Calendar.DATE, daysToAdd);
		return c.getTime();
	}
}
