/*******************************************************************************
 * 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.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import blanco.nlpack.generator.BlancoNLpackGeneratorResultDetailUtil;
import blanco.nlpack.generator.csv.io.BlancoCsvIOException;
import blanco.nlpack.generator.csv.io.BlancoNLpackGeneratorResultDetailCsvReader;
import blanco.nlpack.generator.csv.io.BlancoNLpackGeneratorResultDetailCsvWriter;
import blanco.nlpack.generator.csv.record.BlancoNLpackGeneratorResultDetailCsvRecord;
import blanco.nlpack.generator.resourcebundle.BlancoNLpackGeneratorResourceBundle;
import blanco.nlpack.generator.task.valueobject.BlancoNLpackGeneratorMergeResultDetailProcessInput;

/**
 * 一方を基準としてResultDetailをマージします。
 * 
 * @author IGA Tosiki
 */
public class BlancoNLpackGeneratorMergeResultDetail {
    protected BlancoNLpackGeneratorResourceBundle fBundle = new BlancoNLpackGeneratorResourceBundle();

    protected BlancoNLpackGeneratorMergeResultDetailProcessInput fInput;

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

        final BlancoNLpackGeneratorResultDetailCsvWriter writer = new BlancoNLpackGeneratorResultDetailCsvWriter(
                new BufferedWriter(new FileWriter((input.getTargetfile()))));
        writer.writeTitle();

        merge(writer);

        writer.close();
    }

    private void merge(final BlancoNLpackGeneratorResultDetailCsvWriter writer)
            throws IOException, BlancoCsvIOException {
        final Map<String, BlancoNLpackGeneratorResultDetailCsvRecord> mapRight = new HashMap<String, BlancoNLpackGeneratorResultDetailCsvRecord>();
        BlancoNLpackGeneratorResultDetailUtil.loadResultDetail(new File(fInput
                .getSourceright()), mapRight);

        final BlancoNLpackGeneratorResultDetailCsvReader reader = new BlancoNLpackGeneratorResultDetailCsvReader(
                new BufferedReader(new FileReader(fInput.getSourceleft())));
        for (int index = 0;; index++) {
            if (BlancoNLpackGeneratorResultDetailUtil
                    .checkValidResultDetailRecordByFieldBundleUri(reader
                            .getReader()) == false) {
                // その行は読み飛ばします。
                reader.getReader().readLine();
                continue;
            }

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

            final BlancoNLpackGeneratorResultDetailCsvRecord recordMerge = new BlancoNLpackGeneratorResultDetailCsvRecord();
            recordMerge.setBundleUri(recordLeft.getBundleUri());
            recordMerge.setKey(recordLeft.getKey());
            recordMerge.setInput(recordLeft.getInput());
            if (mapRight.get(recordLeft.getBundleUri()) == null
                    && mapRight.get(getBundleNameWithLocale(recordLeft
                            .getBundleUri())) == null
                    && mapRight.get(getBundleNameWithLocale2(recordLeft
                            .getBundleUri())) == null) {
                // 右辺には見当たらず。無視されたリソースと判断。
                recordMerge.setAction("ignore");
            } else {
                // 右辺に発見。
                Object objFind = mapRight.get(recordLeft.getBundleUri());
                if (objFind == null) {
                    objFind = mapRight.get(getBundleNameWithLocale(recordLeft
                            .getBundleUri()));
                }
                if (objFind == null) {
                    objFind = mapRight.get(getBundleNameWithLocale2(recordLeft
                            .getBundleUri()));
                }
                final BlancoNLpackGeneratorResultDetailCsvRecord recordRight = (BlancoNLpackGeneratorResultDetailCsvRecord) objFind;
                recordMerge.setOutput(recordRight.getInput());
                if (recordMerge.getInput().equals(recordMerge.getOutput())) {
                    // 一致している
                    recordMerge.setAction("miss");
                    // TODO より正確な状況を取得するには、除外辞書との突き合わせが必要。
                } else {
                    recordMerge.setAction("hit");
                    // TODO より正確な状況を取得するには、翻訳フラグメントとの突き合わせが必要。
                }
            }
            writer.writeRecord(recordMerge);
        }
        reader.close();
    }

    private String getBundleNameWithLocale(final String bundleName)
            throws IOException {
        // babel://
        String strUrl = "https://" + bundleName.substring("https://".length());
        URL url = new URL(strUrl);

        String result = "babel://"
                + url.getHost()
                + ".nl_"
                + fBundle.getTargetLocale()
                + url.getPath().substring(0,
                        url.getPath().length() - ".properties".length()) + "_"
                + fBundle.getTargetLocale() + ".properties";
        if (url.getQuery().length() > 0) {
            result += "?" + url.getQuery();
        }

        return result;
    }

    private String getBundleNameWithLocale2(final String bundleName)
            throws IOException {
        // babel://
        String strUrl = "https://" + bundleName.substring("https://".length());
        URL url = new URL(strUrl);

        String result = "babel://"
                + url.getHost()
                + ".nl1"
                + url.getPath().substring(0,
                        url.getPath().length() - ".properties".length()) + "_"
                + fBundle.getTargetLocale() + ".properties";
        if (url.getQuery().length() > 0) {
            result += "?" + url.getQuery();
        }

        return result;
    }
}
