/*
 
Copyright (C) 2009 NTT DATA INTELLILINK CORPORATION
 
This program is free software; you can redistribute it and/or
Modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation, version 2.
 
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied 
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  See the GNU General Public License for more details.
 
*/

package jp.co.intellilink.hinemos.export.conf.calendar;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;

import jp.co.intellilink.hinemos.util.StringListComparator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.clustercontrol.bean.YesNoConstant;
import com.clustercontrol.calendar.bean.AddListTableDefine;
import com.clustercontrol.calendar.bean.CalendarListTableDefine;
import com.clustercontrol.calendar.bean.WeekdayListTableDefine;

/**
 * 日時情報を取得するクラス<br>
 * 
 * @version 1.0.0
 * @since 1.0.0
 */
public class ExportDate {
	//カレンダ基本情報
	private ArrayList calendar = null;
	//カレンダ実行規則情報
	private ArrayList rule = null;
	//カレンダ実行例外情報
	private ArrayList exception = null;
	//有効期間(開始)
	private Date from = null;
	//有効期間(終了)
	private Date to = null;
	
	// ログ出力
	private static Log log = LogFactory.getLog(ExportDate.class);

	public ExportDate(ArrayList calendar, ArrayList rule, ArrayList exception){
		this.calendar = calendar;
		this.rule = rule;
		this.exception = exception;
		
		//有効期間(開始)
		from = (Date)calendar.get(CalendarListTableDefine.VALID_TIME_FROM);
		//有効期間(終了)
		to = (Date)calendar.get(CalendarListTableDefine.VALID_TIME_TO);
	}
	
	/**
	 * 日時情報をExportする。<br>
	 */
	public ArrayList<String> exportDate(Date checkTimestamp) {
    	//CSV出力配列を用意
    	ArrayList<String> csvOutput = new ArrayList<String>();
    	
    	Calendar checkCalendar = Calendar.getInstance();
    	checkCalendar.setTime(checkTimestamp);
    	checkCalendar.set(Calendar.HOUR_OF_DAY, 0);
    	checkCalendar.set(Calendar.MINUTE, 0);
    	checkCalendar.set(Calendar.SECOND, 0);
        Date start = checkCalendar.getTime();
        
    	checkCalendar.set(Calendar.HOUR_OF_DAY, 23);
    	checkCalendar.set(Calendar.MINUTE, 59);
    	checkCalendar.set(Calendar.SECOND, 59);
        Date end = checkCalendar.getTime();
        
		if((from.before(start) && to.after(start))
				|| (from.before(end) && to.after(end))){
			//実行例外をチェック
	    	csvOutput.addAll(isScheduleByException(checkTimestamp));
	    	//実行規則をチェック
	    	csvOutput.addAll(isScheduleByRule(checkTimestamp));
			//ソート
			Collections.sort(csvOutput, new StringListComparator(0));
		}
		
    	return csvOutput;
	}
	
    /**
     * 予定チェック（実行例外）
     * 
     * 実行例外情報にて、指定した日付に実行例外があるかチェックし、CSV文字列を返す。
     * 
     * @param checkTimestamp
	 * @return CSVフォーマット文字列
	 */
	protected ArrayList<String> isScheduleByException(Date checkTimestamp) {
    	//CSV出力配列を用意
    	ArrayList<String> csvOutput = new ArrayList<String>();
    	
    	Calendar checkCalendar = Calendar.getInstance();
    	checkCalendar.setTime(checkTimestamp);
    	checkCalendar.set(Calendar.HOUR_OF_DAY, 0);
    	checkCalendar.set(Calendar.MINUTE, 0);
    	checkCalendar.set(Calendar.SECOND, 0);
        Date start = checkCalendar.getTime();
        
    	checkCalendar.set(Calendar.HOUR_OF_DAY, 23);
    	checkCalendar.set(Calendar.MINUTE, 59);
    	checkCalendar.set(Calendar.SECOND, 59);
        Date end = checkCalendar.getTime();

		Iterator itr = exception.iterator();
		while(itr.hasNext()){
			ArrayList info = (ArrayList)itr.next();
			
			//日時(開始)
			Date from = (Date)info.get(AddListTableDefine.TIME_FROM);
			//日時(終了)
			Date to = (Date)info.get(AddListTableDefine.TIME_TO);
			
			// (from >= start AND to <= end) 
			// OR (from <= start AND to >= start)
			// OR (from <= end AND to >= end)
			if((from.after(start) && to.before(end))
					|| (from.before(start) && to.after(start))
					|| (from.before(end) && to.after(end))){
				StringBuilder output = new StringBuilder();
				output.append("[E]");
				Boolean execute = (Boolean)info.get(AddListTableDefine.EXECUTE);
				if(execute)
					output.append("[" + YesNoConstant.STRING_YES + "]");
				else
					output.append("[" + YesNoConstant.STRING_NO + "]");
				//日時(開始)
				output.append(DateFormat.getDateTimeInstance().format(from));
				output.append("-");
				//日時(終了)
				output.append(DateFormat.getDateTimeInstance().format(to));
				csvOutput.add(output.toString());
			}
		}

        return csvOutput;
    }
	
    /**
     * 予定チェック（実行規則）
     * 
     * 実行規則情報にて、指定した日付に実行可能な時間帯があるかチェックし、CSV文字列を返す。
     * 
     * @param checkTimestamp
	 * @return CSVフォーマット文字列
	 */
	protected ArrayList<String> isScheduleByRule(Date checkTimestamp) {
    	//CSV出力配列を用意
    	ArrayList<String> csvOutput = new ArrayList<String>();
    	
    	SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    	
    	Calendar work = Calendar.getInstance();
    	work.setTime(checkTimestamp);
    	Integer dayOfWeek = work.get(Calendar.DAY_OF_WEEK);

		Iterator itr = rule.iterator();
		while(itr.hasNext()){
			ArrayList info = (ArrayList)itr.next();
			
			if(dayOfWeek.equals((Integer)info.get(WeekdayListTableDefine.WEEKDAY))){
				StringBuilder output = new StringBuilder();
				output.append("[R]");
				//時刻(開始)
				if(info.get(WeekdayListTableDefine.TIME_FROM) instanceof Date)
					output.append(formatter.format((Date)info.get(WeekdayListTableDefine.TIME_FROM)));
				else
					output.append("");
				output.append("-");
				//時刻(終了)
				if(info.get(WeekdayListTableDefine.TIME_TO) instanceof Date)
					output.append(formatter.format((Date)info.get(WeekdayListTableDefine.TIME_TO)));
				else
					output.append("");
				csvOutput.add(output.toString());
			}
		}

        return csvOutput;
    }
}