/*
 
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.operation.logger;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.jboss.aop.Aspect;
import org.jboss.aop.Bind;
import org.jboss.aop.advice.Scope;
import org.jboss.aop.joinpoint.MethodInvocation;

import com.clustercontrol.bean.DayOfWeekConstant;
import com.clustercontrol.bean.Property;
import com.clustercontrol.calendar.factory.AddProperty;
import com.clustercontrol.calendar.factory.CalendarProperty;
import com.clustercontrol.calendar.factory.WeekdayProperty;
import com.clustercontrol.util.PropertyUtil;

/**
 * カレンダ機能 操作ログ出力クラス
 * 
 * @since 1.0.0
 * @version 1.0.0
 * @see jp.co.intellilink.operation.logger.Logger
 */
@Aspect (scope= Scope.PER_VM)
public class Calendar extends Logger {

	/**
	 * カレンダ追加時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->addCalendar(..))")
	public Object addCalendarAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Add Calendar";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[0], CalendarProperty.ID);
			msg.append(", CalendarID=");
			msg.append((String)values.get(0));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * カレンダ変更時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->modifyCalendar(..))")
	public Object modifyCalendarAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Change Calendar";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[0], CalendarProperty.ID);
			msg.append(", CalendarID=");
			msg.append((String)values.get(0));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * カレンダ削除時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->deleteCalendar(..))")
	public Object deleteCalendarAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Delete Calendar";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行例外追加時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->addAddInfo(..))")
	public Object addAddInfoAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Add Exception";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof Property){
			DateFormat format = DateFormat.getDateTimeInstance();
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[1], AddProperty.TIME_FROM);
			msg.append(", From=");
			msg.append(format.format((Date)values.get(0)));

			values = PropertyUtil.getPropertyValue((Property)args[1], AddProperty.TIME_TO);
			msg.append(", To=");
			msg.append(format.format((Date)values.get(0)));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行例外変更時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->modifyAddInfo(..))")
	public Object modifyAddInfoAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Change Exception";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		DateFormat format = DateFormat.getDateTimeInstance();
		if(args.length > 1 && args[1] instanceof Date){
			msg.append(", From=");
			msg.append(format.format((Date)args[1]));
		}
		if(args.length > 2 && args[2] instanceof Date){
			msg.append(", To=");
			msg.append(format.format((Date)args[2]));
		}
		if(args.length > 3 && args[3] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[3], AddProperty.TIME_FROM);
			msg.append(", NewFrom=");
			msg.append(format.format((Date)values.get(0)));

			values = PropertyUtil.getPropertyValue((Property)args[3], AddProperty.TIME_TO);
			msg.append(", NewTo=");
			msg.append(format.format((Date)values.get(0)));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行例外削除時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->deleteAddInfo(..))")
	public Object deleteAddInfoAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Delete Exception";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		DateFormat format = DateFormat.getDateTimeInstance();
		if(args.length > 1 && args[1] instanceof Date){
			msg.append(", From=");
			msg.append(format.format((Date)args[1]));
		}
		if(args.length > 2 && args[2] instanceof Date){
			msg.append(", To=");
			msg.append(format.format((Date)args[2]));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行規則追加時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->addWeekday(..))")
	public Object addWeekdayAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Add Rule";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[1], WeekdayProperty.WEEKDAY);
			msg.append(", Weekday=");
			msg.append(DayOfWeekConstant.stringToType((String)values.get(0)));

			DateFormat format = DateFormat.getTimeInstance();
			values = PropertyUtil.getPropertyValue((Property)args[1], WeekdayProperty.TIME_FROM);
			msg.append(", From=");
			msg.append(format.format((Date)values.get(0)));

			values = PropertyUtil.getPropertyValue((Property)args[1], WeekdayProperty.TIME_TO);
			msg.append(", To=");
			msg.append(format.format((Date)values.get(0)));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行規則変更時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->modifyWeekday(..))")
	public Object modifyWeekdayAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Change Rule";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof Integer){
			msg.append(", Weekday=");
			msg.append((Integer)args[1]);
		}
		DateFormat format = DateFormat.getTimeInstance();
		if(args.length > 1 && args[2] instanceof Date){
			msg.append(", From=");
			msg.append(format.format((Date)args[2]));
		}
		if(args.length > 2 && args[3] instanceof Date){
			msg.append(", To=");
			msg.append(format.format((Date)args[3]));
		}
		if(args.length > 1 && args[4] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[4], WeekdayProperty.WEEKDAY);
			msg.append(", NewWeekday=");
			msg.append(DayOfWeekConstant.stringToType((String)values.get(0)));

			values = PropertyUtil.getPropertyValue((Property)args[4], WeekdayProperty.TIME_FROM);
			msg.append(", NewFrom=");
			msg.append(format.format((Date)values.get(0)));

			values = PropertyUtil.getPropertyValue((Property)args[4], WeekdayProperty.TIME_TO);
			msg.append(", NewTo=");
			msg.append(format.format((Date)values.get(0)));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}

	/**
	 * 実行規則削除時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.calendar.ejb.session.CalendarControllerBean->deleteWeekday(..))")
	public Object deleteWeekdayAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Calendar] Delete Rule";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", CalendarID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof Integer){
			msg.append(", Weekday=");
			msg.append((Integer)args[1]);
		}
		DateFormat format = DateFormat.getTimeInstance();
		if(args.length > 1 && args[2] instanceof Date){
			msg.append(", From=");
			msg.append(format.format((Date)args[2]));
		}
		if(args.length > 2 && args[3] instanceof Date){
			msg.append(", To=");
			msg.append(format.format((Date)args[3]));
		}

		outputLogMessage(title, msg.toString(), invocation);

		return result;
	}
}
