/*******************************************************************************
 * 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.nlpack.generator.task;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.Properties;

import blanco.commons.util.BlancoStringUtil;
import blanco.nlpack.generator.message.BlancoNLpackGeneratorMessage;
import blanco.nlpack.generator.task.valueobject.BlancoNLpackGeneratorConvertProperties2XliffProcessInput;
import blanco.properties.BlancoPropertiesDirectoryParser;
import blanco.properties.BlancoPropertiesUtil;
import blanco.properties.manifest.valueobject.BlancoPropertiesManifest;
import blanco.xliff.BlancoXliffUtil;
import blanco.xliff.valueobject.BlancoXliff;
import blanco.xliff.valueobject.BlancoXliffFile;
import blanco.xliff.valueobject.BlancoXliffTransUnit;

public class BlancoNLpackGeneratorConvertProperties2XliffProcessImpl extends
        BlancoPropertiesDirectoryParser implements
        BlancoNLpackGeneratorConvertProperties2XliffProcess {
    /**
     * メッセージオブジェクト。
     */
    private final BlancoNLpackGeneratorMessage fMsg = new BlancoNLpackGeneratorMessage();

    private BlancoNLpackGeneratorConvertProperties2XliffProcessInput fInput;

    private String fPrevBundleSymbolicName = null;

    private BlancoXliff fXliff = null;

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

        // キャッシュのクリア。
        fPrevBundleSymbolicName = null;

        if (new File(fInput.getSourcedir()).exists() == false) {
            throw new IllegalArgumentException(fMsg.getMbebi001(fInput
                    .getSourcedir()));
        }

        if (new File(fInput.getXliffdir()).exists() == false) {
            new File(fInput.getXliffdir()).mkdirs();
        }

        parse(new File(fInput.getSourcedir()));

        return 0;
    }

    @Override
    protected void beginProperties(final String bundleURI,
            final Properties inputProps,
            final String argPropertiesNameWithPath,
            final BufferedWriter bufPropsWriter) throws IOException {
        final String nextBundleSymbolicName = BlancoPropertiesUtil
                .getHostFromBabelURI(bundleURI);
        if (nextBundleSymbolicName.equals(fPrevBundleSymbolicName)) {
            // キャッシュがヒットしました。リロードしません。
        } else {
            fXliff = BlancoXliffUtil.getXliffInstance(new File(fInput
                    .getXliffdir()), nextBundleSymbolicName);
            fPrevBundleSymbolicName = nextBundleSymbolicName;
        }
    }

    @Override
    protected boolean processPropertiesKey(final String bundleURI,
            final Properties inputProps, final String key,
            final BufferedWriter bufPropsWriter) throws IOException {
        final String inputValue = (String) inputProps.get(key);

        final BlancoXliffTransUnit transUnit = getTransUnitInstance(fXliff,
                bundleURI + "?key=" + key);
        if (BlancoStringUtil.null2Blank(transUnit.getSource()).length() > 0
                && transUnit.getSource().equals(inputValue) == false) {
            // 既に存在する trans-unit の source が変更されました。
            // 一旦 target を削除します。
            transUnit.setTarget(null);

            // TODO 本来的には、旧内容を alt-trans に保存すべきと考えます。
        }
        transUnit.setSource(inputValue);

        return (transUnit.getTarget() != null);
    }

    @Override
    protected void endProperties(final String bundleURI,
            final Properties inputProps,
            final BlancoPropertiesManifest manifest,
            final byte[] bufPropsBytes, final boolean isReplaced)
            throws IOException {

        final String displayPath = BlancoPropertiesUtil
                .getHostFromBabelURI(bundleURI)
                + ": " + BlancoPropertiesUtil.getPathFromBabelURI(bundleURI);

        // 常に保存を試みます。
        switch (BlancoXliffUtil.saveXliffInstance(fXliff, new File(fInput
                .getXliffdir()), BlancoPropertiesUtil
                .getHostFromBabelURI(bundleURI))) {
        case 1:
            if (fInput.getVerbose()) {
                System.out.println("xliff: p2x: create: " + displayPath);
            }
            break;
        case 2:
            if (fInput.getVerbose()) {
                System.out.println("xliff: p2x: update: " + displayPath);
            }
            break;
        case 0:
            break;
        }
    }

    private BlancoXliffTransUnit getTransUnitInstance(final BlancoXliff xliff,
            final String id) {
        BlancoXliffTransUnit transUnit = BlancoXliffUtil
                .getTransUnit(xliff, id);
        if (transUnit != null) {
            // 指定されたidによる trans-unit が既にあれば それを返却。
            return transUnit;
        }

        // 存在しないので作成します。

        // 該当する file を探して、そこに追加が正解です。
        final String path = BlancoPropertiesUtil.getPathFromBabelURI(id);
        BlancoXliffFile file = BlancoXliffUtil.getFile(xliff, path);
        if (file == null) {
            file = new BlancoXliffFile();
            xliff.getFileList().add(file);
            file.setOriginal(path);
            file.setSourceLanguage("en-US");
            file.setTargetLanguage("ja-JP");
        }

        transUnit = new BlancoXliffTransUnit();
        file.getBody().getTransUnitList().add(transUnit);
        transUnit.setId(id);
        return transUnit;
    }
}
