/*
 
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.Date;
import java.util.Iterator;

import jp.co.intellilink.hinemos.util.Config;
import jp.co.intellilink.hinemos.util.EjbConnectionManager;
import jp.co.intellilink.hinemos.util.Messages;
import jp.co.intellilink.hinemos.util.WriteCsvFile;

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

import com.clustercontrol.calendar.bean.CalendarListTableDefine;
import com.clustercontrol.calendar.ejb.session.CalendarController;

/**
 * カレンダ情報を取得するクラス<br>
 * 
 * @version 1.0.0
 * @since 1.0.0
 */
public class ExportCalendarSchedule {

	// ログ出力
	private static Log log = LogFactory.getLog(ExportCalendarSchedule.class);

	/**
	 * カレンダ情報をExportする。<br>
	 */
	public void exportSchedule() {
		log.info(Messages.getMsg("Calendar.Schedule.Start", new String[]{Messages.getMsg("ExportTool.Export")}));

    	//CSV出力配列を用意
    	ArrayList<ArrayList<String>> csvCalendarOutput = new ArrayList<ArrayList<String>>();
    	
		//カレンダ一覧取得
    	ArrayList list = getCalendarList();
    	
	    if(list instanceof ArrayList){
			Iterator itr = list.iterator();
			while(itr.hasNext()){
				ArrayList line = (ArrayList)itr.next();
				
				String calendarId = (String)line.get(CalendarListTableDefine.CALENDAR_ID);
				Object[] args = {calendarId};
				log.info(Messages.getMsg("CalendarID", args));
				
				//カレンダ情報のCSV文字列作成
				csvCalendarOutput = createScheduleCsvFormat(line);
				
				SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
				WriteCsvFile.writeCsvFile(
						Config.getConfig("Export.Dir") + "/CALENDAR_(" + calendarId + ")_" + format.format(new Date()) + ".csv", 
						csvCalendarOutput);
			}
    	}
		
		log.info(Messages.getMsg("Calendar.Schedule.End", new String[]{Messages.getMsg("ExportTool.Export")}));
	}
	
	/**
	 * カレンダ情報のCSV文字列を作成する。<br>
	 * 
	 * @param info カレンダ情報
	 * @return CSVフォーマット文字列
	 */
	protected ArrayList<ArrayList<String>> createScheduleCsvFormat(ArrayList info) {
		ArrayList<ArrayList<String>> csvCalendarOutput = new ArrayList<ArrayList<String>>();
		
		//カレンダID
		String calendarId = (String)info.get(CalendarListTableDefine.CALENDAR_ID);
		//カレンダ実行規則情報を取得
		ArrayList ruleList = getRuleList(calendarId);
		//カレンダ実行例外情報を取得
		ArrayList exceptionList = getExceptionList(calendarId);
		
		ExportDate date = new ExportDate(info, ruleList, exceptionList);
		
		Calendar workCalendar = Calendar.getInstance();
		workCalendar.setTime(new Date());
		workCalendar.set(Calendar.DATE, 1);
		workCalendar.add(Calendar.DATE, (workCalendar.get(Calendar.DAY_OF_WEEK) - 1) * -1);
        
		//開始日付を取得
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(workCalendar.getTime());
		
		//終了日時を取得
		workCalendar.add(Calendar.YEAR, 1);
		Date endDate = workCalendar.getTime();
		
		//開始日付から終了日付までループ
		ArrayList<ArrayList<String>> csvCWeekOutput = null;
		while(startCalendar.getTime().before(endDate)){
			
			//日付ヘッダーを追加
			int dayOfWeek = startCalendar.get(Calendar.DAY_OF_WEEK);
			if(dayOfWeek == Calendar.SUNDAY){
				csvCalendarOutput.add(createHeaderFormat(startCalendar.getTime()));
				csvCWeekOutput = new ArrayList<ArrayList<String>>();
				for(int i = 0; i < 5; i++)
					csvCWeekOutput.add(createEmptyFormat());
			}
			
			ArrayList<String> csvOutput = date.exportDate(startCalendar.getTime());
			int index = 0;
			for(String output : csvOutput){
				ArrayList<String> line = csvCWeekOutput.get(index);
				line.set(dayOfWeek - 1, output);
				index++;
				if(index > 5)
					break;
			}
			
			if(dayOfWeek == Calendar.SATURDAY){
				csvCalendarOutput.addAll(csvCWeekOutput);
				csvCWeekOutput = null;
			}
			
			startCalendar.add(Calendar.DATE, 1);
		}
		
		if(csvCWeekOutput != null)
			csvCalendarOutput.addAll(csvCWeekOutput);
		
		return csvCalendarOutput;
	}
	
	/**
	 * 日付行のCSV文字列を作成する。<br>
	 * 
	 * @param baseDate 基準日
	 * @return CSVフォーマット文字列
	 */
	protected ArrayList<String> createHeaderFormat(Date baseDate) {
		ArrayList<String> csvFormat = new ArrayList<String>();
		
		Calendar baseCalendar = Calendar.getInstance();
		baseCalendar.setTime(baseDate);
        
		for(int i = 0; i < 7; i++){
			csvFormat.add(DateFormat.getDateInstance().format(baseCalendar.getTime()));
			baseCalendar.add(Calendar.DATE, 1);
		}
		
		return csvFormat;
	}
	
	/**
	 * 空白行のCSV文字列を作成する。<br>
	 * 
	 * @return CSVフォーマット文字列
	 */
	protected ArrayList<String> createEmptyFormat() {
		ArrayList<String> csvFormat = new ArrayList<String>();
		
		for(int i = 0; i < 7; i++){
			csvFormat.add("");
		}
		
		return csvFormat;
	}
	
	/**
	 * カレンダ実行例外一覧を取得する。<br>
	 * 
	 * @return カレンダ実行例外一覧
	 */
	protected ArrayList getExceptionList(String calendarId) {

		CalendarController cal = EjbConnectionManager.getConnectionManager().getCalendarController();

		ArrayList list = null;
		try {
			list = cal.getAddList(calendarId);
		} catch (Exception e) {
			log.error(Messages.getMsg("ConnectManagerFailed"), e);
			System.exit(14);
		}
		return list;
	}

	/**
	 * カレンダ実行規則一覧を取得する。<br>
	 * 
	 * @return カレンダ実行規則一覧
	 */
	protected ArrayList getRuleList(String calendarId) {

		CalendarController cal = EjbConnectionManager.getConnectionManager().getCalendarController();

		ArrayList list = null;
		try {
			list = cal.getWeekdayList(calendarId);
		} catch (Exception e) {
			log.error(Messages.getMsg("ConnectManagerFailed"), e);
			System.exit(14);
		}
		return list;
	}
	
	/**
	 * カレンダ一覧を取得する。<br>
	 * 
	 * @return カレンダ一覧
	 */
	protected ArrayList getCalendarList() {

		CalendarController cal = EjbConnectionManager.getConnectionManager().getCalendarController();

		ArrayList list = null;
		try {
			list = cal.getCalendarList();
		} catch (Exception e) {
			log.error(Messages.getMsg("ConnectManagerFailed"), e);
			System.exit(14);
		}
		return list;
	}
}