/*

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.util;


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

import com.clustercontrol.bean.EndStatusConstant;
import com.clustercontrol.bean.JobConstant;
import com.clustercontrol.bean.JudgmentObjectConstant;
import com.clustercontrol.jobmanagement.bean.JobCommandInfo;
import com.clustercontrol.jobmanagement.bean.JobInfo;
import com.clustercontrol.jobmanagement.bean.JobNotificationsInfo;
import com.clustercontrol.jobmanagement.bean.JobObjectInfo;
import com.clustercontrol.jobmanagement.bean.JobTreeItem;
import com.clustercontrol.jobmanagement.bean.JobWaitRuleInfo;
import com.clustercontrol.notify.bean.NotifyRelationInfo;

/**
 * ジョブユーティリティクラス
 * ジョブツリーアイテムに関するユーティリティを格納するクラスです。
 * 
 * @version 1.0.0
 * @since 1.0.0
 */
public class JobUtil {

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

	/**
	 * ジョブツリーアイテムからジョブIDが一致するインスタンスの有無を返す<BR>
	 * ジョブツリーアイテムのツリー階層の全てが検索対象
	 * 
	 * @param jobId ジョブID
	 * @param item ジョブツリーアイテム
	 * @return ジョブIDが一致するジョブツリーアイテムがあればtrue、なければfalse。
	 */
	public static boolean findJobId(String jobId, JobTreeItem item) {
		boolean find = false;

		//ジョブIDをチェック
		JobInfo info = item.getData();
		if(info != null && info instanceof JobInfo){
			if(jobId.compareTo(info.getId()) == 0){
				find = true;
				return find;
			}
		}

		//子JobTreeItemを取得
		JobTreeItem[] childrens = item.getChildrenArray();
		for(int i = 0; i < childrens.length; i++){
			find = findJobId(jobId, childrens[i]);
			if(find){
				break;
			}
		}

		return find;
	}
	
	/**
	 * ジョブツリーアイテムからジョブユニットIDが一致するインスタンスの有無を返す<BR>
	 * ジョブツリーアイテムのツリー階層の全てが検索対象
	 * 
	 * @param jobUnitId ジョブユニットID
	 * @param item ジョブツリーアイテム
	 * @return ジョブIDが一致するジョブツリーアイテムがあればtrue、なければfalse。
	 */
	public static boolean findJobUnitId(String jobUnitId, JobTreeItem item) {
		boolean find = false;

		//ジョブIDをチェック
		JobInfo info = item.getData();
		if(info != null && info instanceof JobInfo){
			if(jobUnitId.compareTo(info.getJobunitId()) == 0){
				find = true;
				return find;
			}
		}

		//子JobTreeItemを取得
		JobTreeItem[] childrens = item.getChildrenArray();
		for(int i = 0; i < childrens.length; i++){
			find = findJobUnitId(jobUnitId, childrens[i]);
			if(find){
				break;
			}
		}

		return find;
	}

	/**
	 * ジョブツリーアイテムの最上位のインスタンスを取得する
	 * 
	 * @param item ジョブツリーアイテム
	 * @return 最上位のジョブツリーアイテム
	 */
	public static JobTreeItem getTopJobTreeItem(JobTreeItem item) {
		if(item == null)
			return null;

		while (item.getParent() != null) {
			if(item.getParent().getData().getType() == JobConstant.TYPE_COMPOSITE){
				item = item.getParent();
				break;
			}
			else{
				item = item.getParent();
			}
		}

		return item;
	}

	/**
	 * ジョブツリーアイテムのジョブ待ち条件情報をチェックする
	 * 
	 * @param item ジョブ待ち条件情報をチェックするジョブツリーアイテム
	 * @return チェック結果
	 */
	public static boolean checkWaitRule(JobTreeItem item) {
		boolean check = true;

		if(item == null)
			return check;

		if(item.getData() != null && item.getData() instanceof JobInfo){
			//ジョブID取得
			String jobId = item.getData().getId();

			//待ち条件情報を取得する
			JobWaitRuleInfo waitRule = item.getData().getWaitRule();
			if(waitRule != null && waitRule instanceof JobWaitRuleInfo && 
					waitRule.getObject() != null && waitRule.getObject().size() > 0){

				for(JobObjectInfo objectInfo : waitRule.getObject()) {
					if(objectInfo.getType() != JudgmentObjectConstant.TYPE_TIME){
						//判定対象のジョブIDが同一階層に存在するかチェック
						boolean find = false;
						String targetJobId = objectInfo.getJobId();
						JobTreeItem[] childrens = item.getParent().getChildrenArray();
						for(int i = 0; i < childrens.length; i++){
							//ジョブIDをチェック
							JobInfo childInfo = childrens[i].getData();
							if(childInfo != null && childInfo instanceof JobInfo && 
									!jobId.equals(childInfo.getId())){
								if(targetJobId.compareTo(childInfo.getId()) == 0){
									find = true;
									break;
								}
							}
						}
						if(!find){
							String args[] = {jobId, targetJobId};
							log.error(Messages.getMsg("ImportTool.Job.1", args));check = false;
							return check;
						}
					}
				}
			}
		}

		//子JobTreeItemを取得
		JobTreeItem[] childrens = item.getChildrenArray();
		for(int i = 0; i < childrens.length; i++){
			check = checkWaitRule(childrens[i]);
			if(!check){
				break;
			}
		}

		return check;
	}

	/**
	 * ジョブツリーアイテムのファシリティIDをチェックする
	 * 
	 * @param item ファシリティIDをチェックするジョブツリーアイテム
	 * @return チェック結果
	 */
	public static boolean checkFacilityId(JobTreeItem item) {
		boolean check = true;

		if(item == null)
			return check;

		if(item.getData() != null && item.getData() instanceof JobInfo){
			//ジョブID取得
			String jobId = item.getData().getId();

			//コマンド情報を取得する
			JobCommandInfo command = item.getData().getCommand();
			if(command != null && command instanceof JobCommandInfo){
				if(!RepositoryUtil.findFacilityId(command.getFacilityID())){
					String args[] = {jobId, command.getFacilityID()};
					log.error(Messages.getMsg("ImportTool.Job.2", args));
					return false;
				}
			}
		}

		//子JobTreeItemを取得
		JobTreeItem[] childrens = item.getChildrenArray();
		for(int i = 0; i < childrens.length; i++){
			check = checkFacilityId(childrens[i]);
			if(!check){
				break;
			}
		}

		return check;
	}

	/**
	 * ジョブツリーアイテムの通知IDをチェックする
	 * 
	 * @param item 通知IDをチェックするジョブツリーアイテム
	 * @return チェック結果
	 */
	public static boolean checkNotifyId(JobTreeItem item) {
		boolean check = true;

		if(item == null)
			return check;

		if(item.getData() != null && item.getData() instanceof JobInfo){
			//ジョブID取得
			String jobId = item.getData().getId();

			//通知情報を取得する
			if(item.getData().getNotifications() != null){
				for(JobNotificationsInfo notify : item.getData().getNotifications()){
					if(notify.getType() == EndStatusConstant.TYPE_NORMAL){
						if(notify.getNotifyId() != null){
							for(NotifyRelationInfo notifyRelation : notify.getNotifyId()) {
								if(!NotifyUtil.findNotifyId(notifyRelation.getNotifyId())){
									String args[] = {jobId, notifyRelation.getNotifyId()};
									log.error(Messages.getMsg("ImportTool.Job.4", args));
									return false;
								}
							}
						}
						break;
					}
				}
			}
		}

		//子JobTreeItemを取得
		JobTreeItem[] childrens = item.getChildrenArray();
		for(int i = 0; i < childrens.length; i++){
			check = checkNotifyId(childrens[i]);
			if(!check){
				break;
			}
		}

		return check;
	}
}