/*
 
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.util.ArrayList;

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.Property;
import com.clustercontrol.repository.factory.NodeProperty;
import com.clustercontrol.repository.factory.ScopeProperty;
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 Repository extends Logger {

	/**
	 * ノード追加時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.repository.ejb.session.RepositoryControllerBean->addNode(..))")
	public Object addNodeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[0], NodeProperty.FACILITY_ID);
			msg.append(", FacilityID=");
			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.repository.ejb.session.RepositoryControllerBean->addScope(..))")
	public Object addScopeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 1 && args[1] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[1], ScopeProperty.FACILITY_ID);
			msg.append(", FacilityID=");
			msg.append((String)values.get(0));
		}
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", ParentFacilityID=");
			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.repository.ejb.session.RepositoryControllerBean->assignNodeScope(..))")
	public Object assignNodeScopeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Repository] Assign Node";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", ParentFacilityID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof String[]){
			for(String facilityID : (String[])args[1]){
				msg.append(", FacilityID=");
				msg.append(facilityID);
			}
		}

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

		return result;
	}

	/**
	 * ノード削除時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.repository.ejb.session.RepositoryControllerBean->deleteNode(..))")
	public Object deleteNodeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", FacilityID=");
			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.repository.ejb.session.RepositoryControllerBean->deleteScope(..))")
	public Object deleteScopeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", FacilityID=");
			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.repository.ejb.session.RepositoryControllerBean->modifyNode(..))")
	public Object modifyNodeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length == 1 && args[0] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[0], NodeProperty.FACILITY_ID);
			msg.append(", FacilityID=");
			msg.append((String)values.get(0));
		}
		else if(args.length == 2 && args[1] instanceof String){
			msg.append(", ParentFacilityID=");
			msg.append((String)args[1]);
		}

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

		return result;
	}

	/**
	 * スコープ変更時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.repository.ejb.session.RepositoryControllerBean->modifyScope(..))")
	public Object modifyScopeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

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

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof Property){
			ArrayList values = PropertyUtil.getPropertyValue((Property)args[0], ScopeProperty.FACILITY_ID);
			msg.append(", FacilityID=");
			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.repository.ejb.session.RepositoryControllerBean->releaseNodeScope(..))")
	public Object releaseNodeScopeAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Repository] Release Node";
		StringBuffer msg = new StringBuffer();

		Object[] args = ((MethodInvocation)invocation).getArguments();
		if(args.length > 0 && args[0] instanceof String){
			msg.append(", ParentFacilityID=");
			msg.append((String)args[0]);
		}
		if(args.length > 1 && args[1] instanceof String[]){
			for(String facilityID : (String[])args[1]){
				msg.append(", FacilityID=");
				msg.append(facilityID);
			}
		}

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

		return result;
	}

	/**
	 * ノード属性変更時のログ出力
	 * 
	 * @param invocation 
	 * @return invokeNext()の結果
	 * @throws Throwable
	 */
	@Bind (pointcut="execution(public void com.clustercontrol.repository.ejb.session.RepositoryControllerBean->setNodeDetail(..))")
	public Object setNodeDetailAdvice(MethodInvocation invocation) throws Throwable {
		Object result = invocation.invokeNext();

		String title = "[Repository] Change Attribute of Node";
		StringBuffer msg = new StringBuffer();

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

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

		return result;
	}
}
