package jp.agentec.abook.abv.bl.common.exception;

import jp.agentec.abook.abv.bl.acms.client.json.AcmsMessageJSON;
import jp.agentec.adf.util.StringUtil;

/**
 * ACMSとの通信で、ACMSがエラーを返した場合、その情報を格納するExceptionです。
 * @author Taejin Hong
 * @version 1.0.0
 */
public class AcmsException extends ABVException {
	private static final long serialVersionUID = -7842266289984677302L;
	private AcmsMessageJSON json;
	
	/**
	 * {@link AcmsException} クラスのインスタンスを初期化します。
	 * @param json ACMSの例外情報を格納した {@link AcmsMessageJSON} インスタンスです。
	 * @since 1.0.0
	 */
	public AcmsException(ABVExceptionCode code, AcmsMessageJSON json) {
		super(code);
		this.json = json;
	}
	
	/**
	 * ACMSが返したHTTP Status コードを返します。
	 * @return　ACMSが返したHTTP Status コード　
	 * @since 1.0.0
	 */
	public int getHttpStatus() {
		if (json != null) {
			return json.httpStatus;
		} else if (getCode() == ABVExceptionCode.S_E_ACMS_0400) {
			return 400;
		} else if (getCode() == ABVExceptionCode.S_E_ACMS_0401) {
			return 401;
		} else if (getCode() == ABVExceptionCode.S_E_ACMS_0403) {
			return 403;
		} else if (getCode() == ABVExceptionCode.S_E_ACMS_0404) {
			return 404;
		} else {
			return -1;
		}
	}
	
	/**
	 * ACMSが返したエラーメッセージの配列を返します。
	 * @return ACMSが返したエラーメッセージの配列です。nullであることもあり得ます。
	 * @since 1.0.0
	 */
	public String[] getMessages() {
		if (json != null) {
			return json.errorMessage;
		} else {
			return null;
		}
	}
	
	/**
	 * ACMSが返したエラーメッセージを一つの文字列にまとめて返します。メッセージが複数の場合、一行で纏めます。
	 * @return　ACMSが返したエラーメッセージ
	 * @since 1.0.0
	 */
	@Override
	public String getMessage() {
		return getMessage(false, false);
	}
	
	/**
	 * サーバ側で設定したユーザ向けのログインエラーメッセージを返します。
	 * 
	 * @return
	 */
	public String getLoginErrorMessage() {
		if (json != null) {
			String message = json.loginErrorMessage;
			if (!StringUtil.isNullOrEmpty(message)) {
				return message;
			}
		}
		return null;
	}
	
	private String getMessage(boolean tab, boolean linefeed) {
		StringBuffer sb = new StringBuffer();
		String[] msgs = getMessages();
		
		if (msgs != null && msgs.length > 0) {
			if (tab && !linefeed) {
				sb.append("\t");
			}
			
			for (String s : getMessages()) {
				if (linefeed) {
					StringUtil.appendLine(sb);
					
					if (tab) {
						sb.append("\t");
					}
				}
				
				sb.append(s);
			}
		}
		
		return sb.toString();
	}
	
	/**
	 * ACMSが返したエラーメッセージの中で、指定したindex番目のメッセージを返します。
	 * @param index　ACMSが返したエラーメッセージの配列のインデックス番号
	 * @return　ACMSが返したエラーメッセージの一つを返します。エラーメッセージの配列にindex番号が存在しないとnullを返します。
	 * @since 1.0.0
	 */
	public String getMessage(int index) {
		String message = null;
		
		if (json.errorMessage != null && json.errorMessage.length > index) {
			message = json.errorMessage[index];
		}
		
		return message;
	}
	
	/**
	 * ACMSが返したエラーメッセージの数を返します。
	 * @return　ACMSが返したエラーメッセージの数です。
	 * @since 1.0.0
	 */
	public int getErrorMessagesLength() {
		int length = 0;
		
		if (getMessages() != null) {
			length = getMessages().length;
		}
		
		return length;
	}
	
	@Override
	public String toString() {
		return String.format("%s: code: %s, message: %s", getClass().getName(), super.getCode(), getMessage(true, true));
	}
}
