/*******************************************************************************
 * Copyright (c) 2008 IGA Tosiki, NTT DATA BUSINESS BRAINS Corp.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IGA Tosiki (NTT DATA BUSINESS BRAINS Corp.) - initial API and implementation
 *******************************************************************************/
/*
 * blanco Framework
 * Copyright (C) 2008 NTT DATA BUSINESS BRAINS CORPORATION
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.pleiades.util.task;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import blanco.commons.util.BlancoStringUtil;
import blanco.pleiades.util.task.valueobject.BlancoPleiadesUtilTranslationNotfound2XliffProcessInput;
import blanco.properties.BlancoPropertiesUtil;
import blanco.xliff.BlancoXliffUtil;
import blanco.xliff.valueobject.BlancoXliff;
import blanco.xliff.valueobject.BlancoXliffFile;
import blanco.xliff.valueobject.BlancoXliffTarget;
import blanco.xliff.valueobject.BlancoXliffTransUnit;

public class BlancoPleiadesUtilTranslationNotfound2XliffProcessImpl implements
        BlancoPleiadesUtilTranslationNotfound2XliffProcess {

    private BlancoPleiadesUtilTranslationNotfound2XliffProcessInput fInput = null;

    private Map<String, String> fNotFoundMap = new HashMap<String, String>();

    public int execute(
            final BlancoPleiadesUtilTranslationNotfound2XliffProcessInput input)
            throws IOException, IllegalArgumentException {
        fInput = input;

        // まず 未発見リストを読み込み。
        final File fileNotfound = new File(fInput.getSourcefile());
        if (fileNotfound.exists() == false) {
            // 存在チェック
            throw new IllegalArgumentException("sourcefile["
                    + fileNotfound.getAbsolutePath() + "]が見つかりません。");
        }
        if (fileNotfound.isFile() == false) {
            // ファイルチェック。
            throw new IllegalArgumentException("sourcefile["
                    + fileNotfound.getAbsolutePath() + "]はファイルではありませんでした。");
        }

        final BufferedInputStream inStream = new BufferedInputStream(
                new FileInputStream(fileNotfound));
        final Properties props = new Properties();
        // プロパティ読み込み。
        props.load(inStream);
        inStream.close();

        // 未翻訳リストを List 化します。
        for (final Enumeration<Object> enumProp = props.elements(); enumProp
                .hasMoreElements();) {
            final Object obj = enumProp.nextElement();
            final String source = BlancoStringUtil.replaceAll((String) obj,
                    "&", "");
            fNotFoundMap.put(source, source);
        }

        final File fileXliffdir = new File(input.getXliffdir());
        final File[] files = fileXliffdir.listFiles();
        if (files == null) {
            return 0;
        }
        for (int index = 0; index < files.length; index++) {
            if (files[index].isFile() == false) {
                continue;
            }
            if (files[index].getName().endsWith(".xlf")) {
                processXliffFile(files[index]);
            }
        }

        return 0;
    }

    private void processXliffFile(final File fileTarget) throws IOException {
        final String bundleSymbolicName = fileTarget.getName().substring(0,
                fileTarget.getName().length() - ".xlf".length());

        final BlancoXliff fXliff = BlancoXliffUtil.getXliffInstance(new File(
                fInput.getXliffdir()), bundleSymbolicName);

        for (int indexFile = 0; indexFile < fXliff.getFileList().size(); indexFile++) {
            final BlancoXliffFile file = fXliff.getFileList().get(indexFile);
            for (int indexTransUnit = 0; indexTransUnit < file.getBody()
                    .getTransUnitList().size(); indexTransUnit++) {
                final BlancoXliffTransUnit transUnit = file.getBody()
                        .getTransUnitList().get(indexTransUnit);
                processTransUnit(transUnit);
            }
        }

        switch (BlancoXliffUtil.saveXliffInstance(fXliff, new File(fInput
                .getXliffdir()), bundleSymbolicName)) {
        case 1:
            // 基本的に、こちらには入らない見込み。
            if (fInput.getVerbose()) {
                System.out.println("pleiades: nf2x: create: "
                        + bundleSymbolicName);
            }
            break;
        case 2:
            if (fInput.getVerbose()) {
                System.out.println("pleiades: nf2x: update: "
                        + bundleSymbolicName);
            }
            break;
        case 0:
            if (fInput.getVerbose()) {
                System.out.println("pleiades: nf2x: none  : "
                        + bundleSymbolicName);
            }
            break;
        }

    }

    private void processTransUnit(final BlancoXliffTransUnit transUnit) {
        if (transUnit.getTranslate() == false) {
            // ここで translate 属性を判定。
            return;
        }

        if (BlancoStringUtil.null2Blank(transUnit.getSource()).length() == 0) {
            // source が無いものは処理できず。
            return;
        }

        if (BlancoPropertiesUtil.isPreferenceKeywords(transUnit.getId())) {
            // プリファランス・キーワードは処理対象外です。
            return;
        }

        final String source = BlancoStringUtil.replaceAll(
                transUnit.getSource(), "&", "");
        if (fNotFoundMap.get(source) != null) {
            // 一度のみ報告。
            fNotFoundMap.remove(fNotFoundMap.get(source));

            if (transUnit.getTarget() == null) {
                transUnit.setTarget(new BlancoXliffTarget());
                transUnit.getTarget().setState("needs-translation");
                transUnit.getTarget().setTarget(transUnit.getSource());
            } else {
                if ("new".equals(transUnit.getTarget().getState())) {
                    transUnit.getTarget().setState("needs-translation");
                }
            }
        }
    }
}
