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

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;

import blanco.commons.util.BlancoStringUtil;
import blanco.xliff.BlancoXliffUtil;
import blanco.xliff.util.task.valueobject.BlancoXliffUtilChangeProcessInput;
import blanco.xliff.valueobject.BlancoXliff;
import blanco.xliff.valueobject.BlancoXliffAltTrans;
import blanco.xliff.valueobject.BlancoXliffFile;
import blanco.xliff.valueobject.BlancoXliffTarget;
import blanco.xliff.valueobject.BlancoXliffTransUnit;

public class BlancoXliffUtilChangeProcessImpl implements
        BlancoXliffUtilChangeProcess {
    private BlancoXliffUtilChangeProcessInput fInput = null;

    private BlancoXliff fXliff = null;

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

        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")) {
                process(fileXliffdir, files[index]);
            }
        }

        return 0;
    }

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

        fXliff = BlancoXliffUtil.getXliffInstance(fileXliffdir,
                bundleSymbolicName);

        for (int indexFile = 0; indexFile < fXliff.getFileList().size(); indexFile++) {
            final BlancoXliffFile file = fXliff.getFileList().get(indexFile);
            processFile(file);
        }

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

    private void processFile(final BlancoXliffFile file) {
        for (int index = 0; index < file.getBody().getTransUnitList().size(); index++) {
            final BlancoXliffTransUnit transUnit = file.getBody()
                    .getTransUnitList().get(index);

            if (transUnit.getTranslate() == false) {
                // 除外項目。
            } else {
                if (fInput.getSettargetifnotexist()) {
                    if (transUnit.getTarget() == null) {
                        final BlancoXliffTarget target = new BlancoXliffTarget();
                        transUnit.setTarget(target);
                        // source を target に複写。
                        target.setTarget(transUnit.getSource());
                        target.setState("x-notarget");
                    }
                }

                if (fInput.getSortalttrans()) {
                    // alt-trans のソート
                    sortAltTrans(transUnit);
                }
            }
        }
    }

    private void sortAltTrans(final BlancoXliffTransUnit transUnit) {
        Collections.sort(transUnit.getAltTransList(),
                new Comparator<BlancoXliffAltTrans>() {
                    public int compare(final BlancoXliffAltTrans arg1,
                            final BlancoXliffAltTrans arg2) {
                        int left = safeParseInt(arg1.getMatchQuality());
                        int right = safeParseInt(arg2.getMatchQuality());
                        if (Math.max(left, right) > 0) {
                            // 降順
                            return right - left;
                        }

                        // tool-id でのソートを試みます。
                        return BlancoStringUtil.null2Blank(arg1.getToolId())
                                .compareTo(
                                        BlancoStringUtil.null2Blank(arg2
                                                .getToolId()));
                    }
                });
    }

    private int safeParseInt(String arg) {
        try {
            if (BlancoStringUtil.null2Blank(arg).length() > 0) {
                if (arg.endsWith("%")) {
                    arg = arg.substring(0, arg.length() - 1);
                }
                return Integer.parseInt(arg);
            }
        } catch (NumberFormatException e) {
        }
        return 0;
    }
}
