/*
 * 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.aspect.resource;

import static jp.sourceforge.mergedoc.pleiades.resource.FileNames.*;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jp.sourceforge.mergedoc.pleiades.log.Logger;
import jp.sourceforge.mergedoc.pleiades.resource.AbstractTranslationDictionary;
import jp.sourceforge.mergedoc.pleiades.resource.Property;
import jp.sourceforge.mergedoc.pleiades.resource.PropertySet;

/**
 * 翻訳用の正規表現辞書です。
 * <p>
 * @author cypher256
 */
public class RegexDictionary {

	/** ロガー */
	private static final Logger log = Logger.getLogger(RegexDictionary.class);

	/** このクラスのシングルトン・インスタンス */
	private static final RegexDictionary singleton = new RegexDictionary();

	/**
	 * 正規表現辞書オブジェクトを取得します。
	 * <p>
	 * @return 翻訳正規表現プロパティー・オブジェクト
	 */
	public static RegexDictionary getInstance() {
		return singleton;
	}

	/** 翻訳正規表現マップ初期容量 */
	private static final int REGEX_MAP_CAPACITY = 1000;

	/** 翻訳正規表現マップ */
	private final Map<Pattern, String> regexMap = new HashMap<Pattern, String>(REGEX_MAP_CAPACITY);

	/** 翻訳スルー正規表現セット初期容量 */
	private static final int REGEX_THROUGH_SET_CAPACITY = 100;

	/** 翻訳スルー正規表現セット */
	private final Set<Pattern> regexThroughSet = new HashSet<Pattern>(REGEX_THROUGH_SET_CAPACITY);

	/**
	 * 正規表現辞書を構築します。
	 */
	private RegexDictionary() {

		File file = AbstractTranslationDictionary.validateExists(TRANS_REGEX_PROP);
		for (Property p : new PropertySet(REGEX_MAP_CAPACITY).load(file)) {
			regexMap.put(Pattern.compile(p.key), p.value);
		}

		file = AbstractTranslationDictionary.validateExists(TRANS_REGEX_THROUGH_PROP);
		for (Property p : new PropertySet(REGEX_THROUGH_SET_CAPACITY).load(file)) {
			regexThroughSet.add(Pattern.compile(p.key));
		}
	}

	/**
	 * 翻訳します。
	 * <p>
	 * @param en 英語文字列
	 * @return 翻訳後日本語文字列
	 */
	public String lookup(String en) {

		for (Entry<Pattern, String> entry : regexMap.entrySet()) {
			Pattern pattern = entry.getKey();
			Matcher matcher = pattern.matcher(en);
			try {
				if (matcher.matches()) {
					String replacement = entry.getValue();
					return matcher.replaceFirst(replacement);
				}
			} catch (RuntimeException e) {
				log.error(e, "正規表現翻訳でエラーが発生しました。" + pattern);
				break;
			}
		}

		for (Pattern pattern : regexThroughSet) {
			Matcher matcher = pattern.matcher(en);
			if (matcher.matches()) {
				return en;
			}
		}

		return null;
	}
}
