/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.fukurou.util;

import java.util.List;
import java.util.ArrayList;


/**
 * エラーメッセージを受け渡すときに使用するクラスです。
 * 結果値として、0:正常 1:警告 2:異常 8:EXCEPTION 9:ORACLEエラー を持っています。
 *
 * @og.group エラー処理
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class ErrorMessage {
	/** 改行コード */
	public static final String CR = System.getProperty("line.separator");	// 5.1.9.0 (2010/08/01) 追加

	/** バッファの初期容量を通常より多い目に設定します。  {@value}  */
	public static final int BUFFER_MIDDLE = 200;							// 5.1.9.0 (2010/08/01) 追加

	/** 結果値 0:正常 {@value} */
	public static final int OK        = 0;
	/** 結果値 1:警告 {@value} */
	public static final int WARNING   = 1;
	/** 結果値 2:異常 {@value} */
	public static final int NG        = 2;
	/** 結果値 8:EXCEPTION {@value} */
	public static final int EXCEPTION = 8;
	/** 結果値 9:ORACLEエラー {@value} */
	public static final int ORCL_ERR  = 9;

	private int			maxKekka	= OK;
	private String		title		= "";
	private final List<ErrMsg> list	= new ArrayList<ErrMsg>();

	private boolean  setPgStep = false; // 3.8.9.5 (2007/09/12)

	/**
	 * デフォルトコンストラクター
	 * 詳細メッセージを指定しないで ErrorMessage を構築します。
	 * (明示しないと、引き通付きコンストラクタのみのクラスになってしまいます。)
	 */
	public ErrorMessage() {
		setTitle( "NO TITLE" );
	}

	/**
	 * タイトルを指定して ErrorMessage を構築します。
	 *
	 * @param	title	タイトル
	 */
	public ErrorMessage( final String title ) {
		setTitle( title );
	}

	/**
	 * 指定されたエラー情報を追加登録します。
	 * これは、行番号０、結果：NG IDは無し(ゼロ文字列)です。
	 *
	 * @param    args String... メッセージの引数(可変引数)
	 */
	public void addMessage( final String... args ) {
		addMessage( 0,NG,"",args );
	}

	/**
	 * 指定されたエラー情報を追加登録します。
	 *
	 * @param	no	行番号
	 * @param	kekka	結果 0:正常 1:警告 2:異常
	 * @param	id	メッセージID
	 * @param    args String... メッセージの引数(可変引数)
	 */
	public void addMessage( final int no,final int kekka,final String id,final String... args ) {
		if( id != null ) {
			ErrMsg msg = new ErrMsg( no,kekka,null,null,id,args );
			list.add( msg );
			if( maxKekka < kekka ) {  maxKekka = kekka; }
		}
	}

	/**
	 * 指定されたエラーオブジェクトを追加登録します。
	 * 追加するErrMsgが、内部の結果値より大きい場合は、その結果値にセットします。
	 * つまり、内部結果値は、登録されたすべてのエラーオブジェクトの最大値です。
	 *
	 * @param	msg	エラーオブジェクト
	 */
	public void addMessage( final ErrMsg msg ) {
		list.add( msg );
		if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }
		if( msg.getPg() != null || msg.getStep() != null ) { setPgStep = true; }  // 3.8.9.5 (2007/09/12)
	}

	/**
	 * 指定された ErrorMessageオブジェクトを追加登録します。
	 * タイトルは元のまま変わりません。
	 * 現状の ErrorMessage の続きに、追加していきます。
	 * 引数の ErrorMessageオブジェクト が null の場合は,何もしません。
	 *
	 * @param   msg ErrorMessageオブジェクト
	 */
	public void append( final ErrorMessage msg ) {
		if( msg != null ) {
			if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }

			ErrMsg[] emsg = msg.toArray();
			for( int i=0; i<emsg.length; i++ ) {
				list.add( emsg[i] );
			}
		}
	}

	/**
	 * 指定された ErrorMessageオブジェクトを行番号指定で追加登録します。
	 * タイトルは元のまま変わりません。
	 * 現状の ErrorMessage の続きに、追加していきます。
	 * 引数の ErrorMessageオブジェクト が null の場合は,何もしません。
	 *
	 * @param	no	行番号
	 * @param   msg ErrorMessageオブジェクト
	 */
	public void append( final int no,final ErrorMessage msg ) {
		if( msg != null ) {
			if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }

			ErrMsg[] emsg = msg.toArray();
			for( int i=0; i<emsg.length; i++ ) {
				list.add( emsg[i].copy( no ) );
			}
		}
	}

	/**
	 *  このリスト内の要素を適切な順序で繰り返し処理する反復子を返します。
	 *
	 * @og.rev 4.0.0 (2004/12/31) 新規追加
	 * @og.rev 4.3.2.0 (2008/09/11) private ⇒ public に変更。
	 *
	 * @return  すべての要素を正しい順序で保持するErrMsg配列
	 */
//	private ErrMsg[] toArray() {
	public ErrMsg[] toArray() {
		return list.toArray( new ErrMsg[list.size()] ) ;
	}

	/**
	 * リスト内のキーと値のマッピングの数を返します。
	 *
	 * @return   リスト内の size
	 */
	public int size() {
		return list.size() ;
	}

	/**
	 *  タイトルを返します。
	 *
	 * @return   タイトル
	 */
	public String getTitle() {
		return title;
	}

	/**
	 *  タイトルをセットします。
	 *
	 * @param	title	タイトル
	 */
	public void setTitle( final String title ) {
		this.title = title;
	}

	/**
	 *  指定の行の位置のエラー行番号を返します。
	 *
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   行番号
	 */
//	public int getNo( final int row ) {
//		return list.get(row).getNo();
//	}

	/**
	 *  指定の行の位置のエラーオブジェクトを返します。
	 *
	 * @og.rev 4.0.0 (2004/12/31) 新規追加
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   エラーオブジェクト
	 */
//	public ErrMsg getErrMsg( final int row ) {
//		return list.get(row);
//	}

	/**
	 *  このエラーメッセージの中で、最大の結果値(エラーの最大レベル)を返します。
	 *
	 * @return   結果   OK, WARNING, NG, ORCL_ERR
	 */
	public int getKekka() {
		return maxKekka;
	}

	/**
	 *  指定の行の位置の結果を返します。
	 *
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   結果  OK, WARNING, NG, EXCEPTION , ORCL_ERR
	 */
//	public int getKekka( final int row ) {
//		return list.get(row).getKekka();
//	}

	/**
	 *  すべてのメッセージが 正常(OK)かを返します。
	 *
	 * @return   結果 すべてOK：true / それ以外 false
	 */
	public boolean isOK() {
		return ( maxKekka == OK );
	}

	/**
	 *  指定の行の位置のエラーコードIDを返します。
	 *
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   エラーコードID
	 */
//	public String getId( final int row ) {
//		return list.get(row).getId();
//	}

	/**
	 *  指定の行の位置のPG名を返します。
	 *
	 * @og.rev 3.8.9.5 (2007/09/12) 新規作成
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   PG名
	 */
//	public String getPg( final int row ) {
////		return ((ErrMsg)list.get(row)).getPg();
//		return (list.get(row)).getPg();		// 4.0.0.0 (2007/09/25)
//	}

	/**
	 *  指定の行の位置のステップ名を返します。
	 *
	 * @og.rev 3.8.9.5 (2007/09/12) 新規作成
	 * @og.rev 4.3.2.0 (2008/09/11) 廃止
	 *
	 * @param    row 行の位置
	 *
	 * @return   ステップ名
	 */
//	public String getStep( final int row ) {
////		return ((ErrMsg)list.get(row)).getStep();
//		return (list.get(row)).getStep();		// 4.0.0.0 (2007/09/25)
//	}

	/**
	 *  配列中にPG名またはステップ名が設定されているかを返します。
	 *
	 * @og.rev 3.8.9.5 (2007/09/12) 新規作成
	 *
	 * @return   PG名またはステップ名が設定されているか
	 */
	public boolean isSetPgStep() {
		return setPgStep;
	}

	/**
	 *  メッセージの連結リストを返します。
	 *
	 * @return   メッセージの連結リスト
	 */
	@Override
	public String toString() {
//		StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
		StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
//		rtn.append( getTitle() ).append( HybsSystem.CR );
		rtn.append( getTitle() ).append( CR );
		ErrMsg[] msg = list.toArray( new ErrMsg[list.size()] );
		for( int i=0; i<msg.length; i++ ) {
			rtn.append( msg[i] );
//			rtn.append( HybsSystem.CR );
			rtn.append( CR );
		}
		return rtn.toString();
	}
}
