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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import blanco.commons.io.Native2AsciiWriter;
import blanco.commons.util.BlancoStringUtil;
import blanco.nlpack.generator.BlancoNLpackGeneratorConstants;
import blanco.nlpack.generator.BlancoNLpackGeneratorResultDetailUtil;
import blanco.nlpack.generator.csv.io.BlancoCsvIOException;
import blanco.nlpack.generator.csv.io.BlancoNLpackGeneratorResultDetailCsvReader;
import blanco.nlpack.generator.csv.record.BlancoNLpackGeneratorResultDetailCsvRecord;
import blanco.nlpack.generator.task.valueobject.BlancoNLpackGeneratorTranslationFragmentToPleiadesProcessInput;
import blanco.properties.BlancoPropertiesUtil;

/**
 * 翻訳フラグメントを Pleiades形式プロパティファイルへと変換します。
 * 
 * @author IGA Tosiki
 */
public class BlancoNLpackGeneratorTranslationFragmentToPleiades {
    private BlancoNLpackGeneratorTranslationFragmentToPleiadesProcessInput fInput = null;

    public void process(
            final BlancoNLpackGeneratorTranslationFragmentToPleiadesProcessInput input)
            throws IOException, BlancoCsvIOException {
        fInput = input;

        if (BlancoStringUtil.null2Blank(input.getSourcedir()).length() > 0) {
            final File sourceDir = new File(input.getSourcedir());
            final File targetDir = new File(input.getTargetdir());
            final File[] sourceFiles = sourceDir.listFiles();
            if (sourceFiles == null) {
                return;
            }
            for (int index = 0; index < sourceFiles.length; index++) {
                if (sourceFiles[index].isFile() == false) {
                    continue;
                }
                if (sourceFiles[index].getName().endsWith(".csv") == false) {
                    continue;
                }
                final String name = sourceFiles[index].getName();
                final File targetFile = new File(targetDir.getAbsolutePath()
                        + "/"
                        + name.substring(0, name.length() - ".csv".length())
                        + ".properties");
                processFile(sourceFiles[index], targetFile);
            }
        } else {
            final File sourceFile = new File(input.getSourcefile());
            final File targetFile = new File(input.getTargetfile());
            processFile(sourceFile, targetFile);
        }
    }

    private void processFile(final File sourceFile, final File targetFile)
            throws IOException, BlancoCsvIOException {
        // TODO 文字コードは外部に出す必要があります。
        final BlancoNLpackGeneratorResultDetailCsvReader reader = new BlancoNLpackGeneratorResultDetailCsvReader(
                new BufferedReader(new InputStreamReader(new FileInputStream(
                        sourceFile), "Windows-31J")));
        final BufferedWriter writer = new BufferedWriter(new FileWriter(
                targetFile));
        try {
            writer
                    .write("# [#xxxxx] contributed by "
                            + fInput.getContributor());
            writer.newLine();
            writer.write("# blancoNLpackGenerator ("
                    + BlancoNLpackGeneratorConstants.VERSION
                    + "): TranslationFragment to Pleiades.");
            writer.newLine();
            if (fInput.getIsoutputdate()) {
                writer.write("# " + new Date().toString());
                writer.newLine();
            }

            final Map<String, BlancoNLpackGeneratorResultDetailCsvRecord> mapExist = new HashMap<String, BlancoNLpackGeneratorResultDetailCsvRecord>();
            for (;;) {
                if (fInput.getIscheckbundleuriasbabel()) {
                    if (BlancoNLpackGeneratorResultDetailUtil
                            .checkValidResultDetailRecordByFieldBundleUri(reader
                                    .getReader()) == false) {
                        // その行は読み飛ばします。
                        final String line = reader.getReader().readLine();
                        if (line.length() > 0) {
                            writer.write("# " + line);
                        }
                        writer.newLine();
                        continue;
                    }
                }

                final BlancoNLpackGeneratorResultDetailCsvRecord record = reader
                        .readRecord();
                if (record == null) {
                    break;
                }

                if (BlancoStringUtil.null2Blank(record.getNote()).length() > 0) {
                    if (record.getNote().indexOf('\n') >= 0) {
                        // 改行が含まれるNoteは出力しません。
                        writer
                                .write(Native2AsciiWriter
                                        .encodeNative2AsciiComment("# Note: <改行の含まれるNote>"));
                        writer.newLine();
                    } else {
                        writer.write(Native2AsciiWriter
                                .encodeNative2AsciiComment("# Note: "
                                        + record.getNote()));
                        writer.newLine();
                    }
                }

                if (mapExist.get(record.getInput()) != null) {
                    throw new IllegalArgumentException("重複チェック: 同じinput["
                            + record.getInput()
                            + "]が重複して現れました。入力データを修正してください。["
                            + record.getBundleUri() + "]");
                } else {
                    mapExist.put(record.getInput(), record);
                }
                writer.write(BlancoPropertiesUtil.getPropertiesLine(record
                        .getInput(), record.getOutput()));
                writer.newLine();
            }
        } finally {
            reader.close();
            writer.close();
        }
    }
}
