/*******************************************************************************
 * 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.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import blanco.commons.util.BlancoStringUtil;
import blanco.nlpack.generator.BlancoNLpackGeneratorResultDetailUtil;
import blanco.nlpack.generator.csv.io.BlancoCsvIOException;
import blanco.nlpack.generator.csv.record.BlancoNLpackGeneratorResultDetailCsvRecord;
import blanco.nlpack.generator.task.valueobject.BlancoNLpackGeneratorValidateResultDetailProcessInput;

public class BlancoNLpackGeneratorValidateResultDetail {
    protected static final String[] CHECK_STRING_LIST = { "{0}", "{1}", "{2}",
            "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}" };

    protected static final char[] CHECK_CHAR_LIST = { '{', '}', '\n', };

    // 可能性のみチェック。
    protected static final char[] CHECK_CHAR_LIST2 = { '\'', '&', '?', '<',
            '>', };

    public void process(
            final BlancoNLpackGeneratorValidateResultDetailProcessInput input)
            throws IOException, BlancoCsvIOException {
        final File fileInput = new File(input.getSourcefile());

        final List<BlancoNLpackGeneratorResultDetailCsvRecord> list = new ArrayList<BlancoNLpackGeneratorResultDetailCsvRecord>();
        BlancoNLpackGeneratorResultDetailUtil.loadResultDetail(fileInput, list);

        final List<BlancoNLpackGeneratorResultDetailCsvRecord> validateLogList = new ArrayList<BlancoNLpackGeneratorResultDetailCsvRecord>();

        int countError = 0;
        int countWarn = 0;

        for (int index = 0; index < list.size(); index++) {
            final BlancoNLpackGeneratorResultDetailCsvRecord record = list
                    .get(index);
            if (BlancoStringUtil.null2Blank(record.getInput()).length() == 0
                    || BlancoStringUtil.null2Blank(record.getOutput()).length() == 0) {
                // 無視します。
                continue;
            }

            boolean isWarn = false;
            boolean isError = false;

            final BlancoNLpackGeneratorResultDetailCsvRecord recordLog = new BlancoNLpackGeneratorResultDetailCsvRecord();
            recordLog.setBundleUri(record.getBundleUri());
            recordLog.setAction(record.getAction());
            recordLog.setKey(record.getKey());
            recordLog.setInput(record.getInput());
            recordLog.setOutput(record.getOutput());
            // Noteは初期化。
            recordLog.setNote("");

            // 翻訳前、翻訳後で内容チェック (文字)
            for (int indexCheck = 0; indexCheck < CHECK_CHAR_LIST2.length; indexCheck++) {
                if (isEqualByChar(record.getInput(), record.getOutput(),
                        CHECK_CHAR_LIST2[indexCheck]) == false) {
                    recordLog.setNote(recordLog.getNote() + "文字不一致の可能性: ["
                            + CHECK_CHAR_LIST2[indexCheck] + "] ");
                    isWarn = true;
                }
            }

            // 翻訳前、翻訳後で内容チェック (文字列)
            for (int indexCheck = 0; indexCheck < CHECK_STRING_LIST.length; indexCheck++) {
                if (isEqualByString(record.getInput(), record.getOutput(),
                        CHECK_STRING_LIST[indexCheck]) == false) {
                    recordLog.setNote(recordLog.getNote() + "文字列不一致: ["
                            + CHECK_STRING_LIST[indexCheck] + "] ");
                    isError = true;
                }
            }

            // 翻訳前、翻訳後で内容チェック (文字)
            for (int indexCheck = 0; indexCheck < CHECK_CHAR_LIST.length; indexCheck++) {
                if (isEqualByChar(record.getInput(), record.getOutput(),
                        CHECK_CHAR_LIST[indexCheck]) == false) {
                    recordLog.setNote(recordLog.getNote() + "文字不一致: ["
                            + CHECK_CHAR_LIST[indexCheck] + "] ");
                    isError = true;
                }
            }

            // ＆が含まれるものは基本的にエラー呼ばわりします。
            if (record.getInput().indexOf('&') >= 0) {
                recordLog.setNote(recordLog.getNote() + "inputに '&' が含まれます ");
                isError = true;
            }
            if (record.getOutput().indexOf('&') >= 0) {
                recordLog.setNote(recordLog.getNote() + "outputに '&' が含まれます ");
                isError = true;
            }

            if (input.getCheckendoflineperiod()) {
                // 翻訳前、翻訳後で内容チェック (ピリオド)
                if (record.getInput().trim().endsWith(".")
                        && (record.getOutput().trim().endsWith("。") == false && record
                                .getOutput().trim().endsWith(".") == false)) {
                    recordLog.setNote(recordLog.getNote()
                            + "文末不一致: 英文が[.]で終わっているのに、和文は[。]および[.]で終わっていません。 ");
                    isError = true;
                }
                if (record.getInput().trim().endsWith(".") == false
                        && ((record.getOutput().trim().endsWith("。") || record
                                .getOutput().trim().endsWith(".")))) {
                    recordLog.setNote(recordLog.getNote()
                            + "文末不一致: 英文が[.]で終わっていないのに、和文は[。]または[.]で終わっています。 ");
                    isError = true;
                }
            }

            if (input.getCheckcolon()) {
                if (isEqualByChar(record.getInput(), record.getOutput(), ':') == false) {
                    recordLog.setNote(recordLog.getNote() + "文字不一致: [" + ':'
                            + "] ");
                    isError = true;
                }
            }

            if (recordLog.getNote().length() > 0) {
                validateLogList.add(recordLog);
            }

            if (isWarn) {
                countWarn++;
            }
            if (isError) {
                countError++;
            }
        }

        BlancoNLpackGeneratorResultDetailUtil.saveResultDetail(new File(input
                .getTargetfile()), validateLogList);

        System.out.println("エラー: " + countError);
        System.out.println("警告  : " + countWarn);
    }

    private static boolean isEqualByString(final String input,
            final String output, final String checkString) {
        boolean isExistInput = input.indexOf(checkString) >= 0;
        boolean isExistOutput = output.indexOf(checkString) >= 0;
        if (isExistInput != isExistOutput) {
            return false;
        }
        return true;
    }

    private static boolean isEqualByChar(final String input,
            final String output, final char checkChar) {
        int countInput = count(input, checkChar);
        int countOutput = count(output, checkChar);
        if (countInput != countOutput) {
            return false;
        }
        return true;
    }

    private static int count(final String look, final char check) {
        int counter = 0;
        for (int index = 0; index < look.length(); index++) {
            if (look.charAt(index) == check) {
                counter++;
            }
        }
        return counter;
    }
}
