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

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import blanco.commons.util.BlancoStreamUtil;
import blanco.properties.message.BlancoPropertiesMessage;

/**
 * プラグインディレクトリを入力して、プラグインjarを出力します。
 * 
 * TODO blancoPropertiesに移行すべきクラスのひとつ。
 * 
 * @author IGA Tosiki
 */
public class BlancoPropertiesDirectory2Jar {
    /**
     * メッセージオブジェクト。
     */
    private final BlancoPropertiesMessage fMsg = new BlancoPropertiesMessage();

    private File fInputDir = null;

    private File fOutputDir = null;

    /**
     * プラグインディレクトリを プラグインjarに変換します。
     * 
     * @param argInput
     *            処理への入力パラメータ。
     * @throws IOException
     *             入出力例外が発生した場合。
     */
    public void process(final File inputDir, final File outputDir)
            throws IOException {
        fInputDir = inputDir;
        fOutputDir = outputDir;

        System.out.println("babel: plugin dir->jar begin: ["
                + fInputDir.getAbsolutePath() + "]->["
                + fOutputDir.getAbsolutePath() + "].");

        if (fInputDir.exists() == false) {
            throw new IllegalArgumentException(fMsg.getMbprmj01(fInputDir
                    .getAbsolutePath()));
        }
        if (fInputDir.isDirectory() == false) {
            throw new IllegalArgumentException(fMsg.getMbprmj02(fInputDir
                    .getAbsolutePath()));
        }

        // 出力先ディレクトリを作成。
        fOutputDir.mkdirs();

        final File[] dirs = fInputDir.listFiles();
        if (dirs != null) {
            for (int index = 0; index < dirs.length; index++) {
                if (dirs[index].isDirectory()) {
                    // ディレクトリだけを処理します。
                    processPluginDir(dirs[index]);
                }
            }
        }

        System.out.println("babel: plugin dir->jar end.");
    }

    private void processPluginDir(final File dirPlugin) throws IOException {
        final ZipOutputStream outStream = new ZipOutputStream(
                new BufferedOutputStream(new FileOutputStream(fOutputDir
                        .getAbsolutePath()
                        + "/" + dirPlugin.getName() + ".jar")));
        try {
            processEvery(dirPlugin, "", outStream);

            outStream.flush();
        } finally {
            outStream.close();
        }
    }

    private void processEvery(final File dirTarget, final String subDir,
            final ZipOutputStream outStream) throws IOException {

        final File[] files = dirTarget.listFiles();
        if (files != null) {
            for (int index = 0; index < files.length; index++) {
                if (files[index].isDirectory()) {
                    String nextDir = subDir;
                    if (nextDir.length() > 0) {
                        nextDir += "/";
                    }
                    nextDir += files[index].getName();
                    processEvery(files[index], nextDir, outStream);
                } else {
                    String fileName = files[index].getName();
                    if (subDir.length() > 0) {
                        fileName = subDir + "/" + fileName;
                    }

                    final ZipEntry entry = new ZipEntry(fileName);
                    outStream.putNextEntry(entry);

                    final InputStream inStream = new BufferedInputStream(
                            new FileInputStream(files[index]));

                    BlancoStreamUtil.copy(inStream, outStream);

                    inStream.close();

                    outStream.closeEntry();
                }
            }
        }
    }
}
