/*
 * Copyright (c) 2005- Shinji Kashihara.
 * All rights reserved. This program are made available under
 * the terms of the Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at epl-v10.html.
 */
package jp.sourceforge.mergedoc.pleiades.generator.nls;

import jp.sourceforge.mergedoc.pleiades.generator.ValidationResult;
import jp.sourceforge.mergedoc.pleiades.generator.Validator;
import jp.sourceforge.mergedoc.pleiades.log.Logger.Level;
import jp.sourceforge.mergedoc.pleiades.resource.Property;
import jp.sourceforge.mergedoc.pleiades.resource.PropertySet;

/**
 * ヘルプ翻訳バリデーター・クラスです。
 * 訳語を検証し、結果をログ出力します。
 * <p>
 * @author cypher256
 */
public class J10nHelpValidator extends Validator {

	/** 検証結果ログ出力をプロパティー・エスケープする場合は true */
	private static final boolean isLogEscape = false;

	/** 訳注 */
	private String transNote;

	/**
	 * バリデーターを構築します。
	 * <p>
	 * @param logFileName ログ・ファイル名。例) "props/validator.log"
	 * @param existsProps 重複チェックに使用する既存プロパティー
	 */
	public J10nHelpValidator(String logFileName, PropertySet... existsProps) {
		super(logFileName, existsProps);
	}

	/**
	 * ログ・ファイルのログ・レベルを取得します。
	 * オーバーライドしない場合のデフォルトでは Level.WARN です。
	 * <p>
	 * @return ログ・ファイルのログ・レベル
	 */
	protected Level getLogFileLogLevel() {
		return Level.ERROR;
	}

	/**
	 * 訳語を検証します。
	 * <p>
	 * @param p プロパティー
	 * @param name ファイル名などの識別子
	 * @return 検証結果
	 */
	@Override
	public ValidationResult validate(Property p, String name) {

		transNote = "";

		for (String s : new String[]{"◆", "▲"}) {
			String pattern = "(?s)(.*?)(" + s + "(.+?)" + s + ".+?】)(.*)";
			while (p.value.matches(pattern)) {
				transNote += p.value.replaceFirst(pattern, "$2");
				p.value = p.value.replaceFirst(pattern, "$1$3$4");
			}
		}

		String pattern = "(?s).*[「>](.+?★).*";
		while (p.value.matches(pattern)) {
			transNote += p.value.replaceFirst(pattern, "$1");
			p.value = p.value.replaceFirst("★", "");
		}
		pattern = "(?s)(.*?)(【.+?】)(.*)";
		while (p.value.matches(pattern)) {
			transNote += p.value.replaceFirst(pattern, "$2");
			p.value = p.value.replaceFirst(pattern, "$1$3");
		}

		return super.validate(p, name);
	}

	/**
	 * 末尾文字を検証します。
	 * <p>
	 * @param en 英語
	 * @param ja 日本語
	 * @param vc 検証コンテキスト
	 */
	@Override
	protected void validateSuffix(String en, String ja, ValidationContext vc) {
		// チェックしない
	}

	/**
	 * 対訳正規表現プロパティー・ファイルを参照し、
	 * 翻訳が不正な場合は、その対訳正規表現プロパティーを取得します。
	 * <p>
	 * @param en 英語
	 * @param ja 日本語
	 * @return 正しい場合は null。不正な場合は対訳正規表現プロパティー。
	 */
	protected Property getIllegalTranslationProperty(String en, String ja) {

		Property p = super.getIllegalTranslationProperty(en, ja);
		if (p != null) {
			// ヘルプ:	「プロパティー」ビュー などを許容する
			// UI:		プロパティー・ビュー
			if (p.value.contains("・ビュー") && ja.contains("」ビュー")) {
				return null;
			}
		}
		return p;
	}

	/**
	 * 検証コンテキストを作成します。
	 * @param en 英語
	 * @param ja 日本語
	 * @param name 識別子
	 * @return
	 */
	protected ValidationContext createValidationContext(String en, String ja, String name) {
		return new J10nHelpValidationContext(en, ja, name);
	}

	/**
	 * 検証コンテキスト・クラスです。
	 */
	protected class J10nHelpValidationContext extends ValidationContext {

		/**
		 * 検証コンテキスト・クラスを構築します。
		 * @param en 英語
		 * @param ja 日本語
		 * @param name 識別子
		 */
		public J10nHelpValidationContext(String en, String ja, String name) {
			super(en, ja, name);
		}

		/**
		 * メッセージをフォーマットします。
		 * @param msg メッセージ
		 */
		protected String formatMessage(String msg) {

			String e = isLogEscape ? Property.escapeKey(en) : en;
			String j = isLogEscape ? Property.escapeKey(ja) : ja;

			StringBuilder m = new StringBuilder("\n");
			m.append("英: " + e + "\n");
			m.append("日: " + j + "\n");
			if (transNote.length() > 0) {
				m.append("訳注: " + transNote + "\n");
			}
			m.append("内容: " + msg + "\n");

			if (name != null && name.length() > 0) {
				m.insert(0, name);
			}
			String indent = "      ";
			return m.toString().replace("\n", "\n" + indent);
		}
	}
}
