/*
 * 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 java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;

import jp.sourceforge.mergedoc.org.apache.commons.lang.StringUtils;
import jp.sourceforge.mergedoc.pleiades.log.Logger;
import jp.sourceforge.mergedoc.pleiades.log.Logger.Level;
import jp.sourceforge.mergedoc.pleiades.log.SystemOutLogger;
import jp.sourceforge.mergedoc.pleiades.resource.Files;
import jp.sourceforge.mergedoc.pleiades.resource.Mnemonics;
import jp.sourceforge.mergedoc.pleiades.resource.Property;
import jp.sourceforge.mergedoc.pleiades.resource.PropertySet;
import jp.sourceforge.mergedoc.pleiades.resource.TranslationString;

/**
 * 言語パックから、UI に関する日本語訳を抽出し、Pleiades 形式の
 * プロパティー・ファイルに出力するクラスです。
 * <p>
 * @author cypher256
 */
public class UIExtractor extends AbstractExtractor {

	/**
	 * 抽出を開始するための main メソッドです。
	 * <p>
	 * @param args NLS 取得元プラグイン確認デバッグ・ログ出力用の英語リソース文字列
	 * @throws IOException 入出力例外が発生した場合
	 */
	public static void main(String... args) throws IOException {

		// PropertySet のログ抑止
		Logger.init(SystemOutLogger.class, Level.ERROR);

		// 第二引数は debugEnValue
		new UIExtractor().run("ui", "");
	}

	/**
	 * 指定されたプラグイン・フォルダーに存在する言語パックをロードし、
	 * プロパティーを生成します。
	 * <p>
	 * @param pluginsFolder プラグイン・フォルダー
	 * @throws IOException 入出力例外が発生した場合
	 */
	@Override
	protected void extractPlugins(File pluginsFolder) throws IOException {

		Map<String, PropertySetUnit> pluginMap = new HashMap<String, PropertySetUnit>();
		File[] pluginFiles = pluginsFolder.listFiles();
		Arrays.sort(pluginFiles); // 昇順

		// 日本語と英語のプロパティーをロード
		for (File pluginFile : pluginFiles) {

			// プラグイン・オブジェクト作成
			Plugin plugin = pluginsFolder.getName().equals("plugins")
				? new Plugin(pluginFile)
				: new Feature(pluginFile);

			String msg = "%-46s en:%4d ja:%4d %s";
			log.info(String.format(msg,
					plugin.getId(),
					plugin.getEnPropertySet().size(),
					plugin.getJaPropertySet().size(),
					Files.relativePath(inNlsFolder, pluginFile)));

			String pluginId = plugin.getId();
			PropertySetUnit propUnit = pluginMap.get(pluginId);
			if (propUnit == null) {
				propUnit = new PropertySetUnit();
				pluginMap.put(pluginId, propUnit);
			}
			propUnit.getEnPropertySet().putAll(plugin.getEnPropertySet());
			propUnit.getJaPropertySet().putAll(plugin.getJaPropertySet());
		}
		String pluginPath = Files.relativePath(inNlsFolder, pluginsFolder);

		// 日本語と英語のプロパティーでキーが一致するものからプロパティー作成
		for (Entry<String, PropertySetUnit> entry : pluginMap.entrySet()) {

			PropertySetUnit propUnit = entry.getValue();
			PropertySet enProp = propUnit.getEnPropertySet();
			PropertySet jaProp = propUnit.getJaPropertySet();
			PropertySet outProp = new PropertySet();

			for (Property ja : jaProp) {

				String enValue = enProp.get(ja.key);

				if (StringUtils.isNotEmpty(enValue) && !enValue.equals(ja.value)) {

					if (ja.value.matches("\\p{ASCII}+")) {
						continue;
					}
					// 原文にない NLS 固有の訳注が含まれているものは除外
					if (ja.value.contains("の翻訳版です") || ja.value.contains("のためのドイツ語")) {
						continue;
					}

					// BIRT の日本語に含まれる原文を除去
					String s = "/ [en]-(";
					if (ja.value.contains(s)) {
						ja.value = ja.value.replaceFirst("\\s*" + Pattern.quote(s) + ".+", "");
					}

					outProp.put(enValue, ja.value);

					// デバッグ
					if (StringUtils.isNotBlank(debugEnValue)) {

						String en = Mnemonics.removeEn(enValue).toLowerCase();
						String trimEn = new TranslationString(en).trimForce();
						if (trimEn.contains(debugEnValue)) {

							String pluginBaseName = pluginsFolder.getPath().replace("\\", "/");
							pluginBaseName = pluginBaseName.replaceFirst(".+/([^/]+?/[^/]+?)", "$1");
							String jaValue = Mnemonics.removeJa(ja.value);

							System.out.println(pluginBaseName + "/" + ja.key + "=" +
								new TranslationString(jaValue).trimForce());
						}
					}
				}
			}

			// プロパティー・ファイルへ出力
			int outPropSize = outProp.size();
			if (outPropSize > 0) {

				count += outPropSize;

				// デバッグ文字列が設定されていない場合は出力
				if (StringUtils.isBlank(debugEnValue)) {

					String pluginId = entry.getKey();
					String outFileName = pluginPath.replace('\\', '@') + "@" + pluginId + ".properties";
					File outFile = new File(extractTempFolder, outFileName);
					outProp.store(outFile, "eclipse.org 言語パック抽出プロパティー (プラグイン別)");
				}
			}

			// 日本語プロパティが存在しない場合のプロパティー作成
			for (Property en : enProp) {

				String jaValue = jaProp.get(en.key);

				if (jaValue == null &&
					en.value != null &&
					en.value.matches("(?s).*[a-zA-Z].*") &&
					en.value.length() > 1) {

					missingProp.put(en.value, "");
				}
			}
		}
	}
}
