/*******************************************************************************
 * 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.html.normalizer.task;

import java.io.File;
import java.io.IOException;

import blanco.commons.util.BlancoFileUtil;
import blanco.html.normalizer.message.BlancoHtmlNormalizerMessage;
import blanco.html.normalizer.task.valueobject.BlancoHtmlNormalizeProcessInput;
import blanco.html.normalizer.util.BlancoHtmlNormalizerUtil;

/**
 * HTMLを正常化する処理です。
 * 
 * @author IGA Tosiki
 */
public class BlancoHtmlNormalizeProcessImpl implements
        BlancoHtmlNormalizeProcess {
    /**
     * 処理の入力。
     */
    protected BlancoHtmlNormalizeProcessInput fInput;

    /**
     * メッセージ。
     */
    protected BlancoHtmlNormalizerMessage fMsg = new BlancoHtmlNormalizerMessage();

    /**
     * クラスをインスタンス化して処理を実行する際のエントリポイントです。
     * 
     * @param input
     *            処理の入力パラメータ。
     * @return 処理の実行結果。
     * @throws IOException
     *             入出力例外が発生した場合。
     * @throws IllegalArgumentException
     *             入力値に不正が見つかった場合。
     */
    public int execute(final BlancoHtmlNormalizeProcessInput input)
            throws IOException, IllegalArgumentException {
        fInput = input;

        final File sourceDir = new File(fInput.getSourcedir());
        final File targetDir = new File(fInput.getTargetdir());

        if (sourceDir.exists() == false) {
            throw new IllegalArgumentException(fMsg.getMbhtni01(fInput
                    .getSourcedir()));
        }
        if (sourceDir.isDirectory() == false) {
            throw new IllegalArgumentException(fMsg.getMbhtni02(fInput
                    .getSourcedir()));
        }
        if (targetDir.exists() == false) {
            if (targetDir.mkdirs() == false) {
                throw new IllegalArgumentException(fMsg.getMbhtni03(fInput
                        .getTargetdir()));
            }
        } else if (targetDir.isDirectory() == false) {
            throw new IllegalArgumentException(fMsg.getMbhtni04(fInput
                    .getTargetdir()));
        }
        if (sourceDir.getCanonicalPath().equals(targetDir.getCanonicalPath())) {
            throw new IllegalArgumentException(fMsg.getMbhtni05(fInput
                    .getSourcedir(), fInput.getTargetdir()));
        }

        process();

        return 0;
    }

    /**
     * HTMLを正常化する処理の具体的な内容。
     * 
     * @throws IOException
     *             入出力例外が発生した場合。
     */
    protected void process() throws IOException {
        final File sourceDir = new File(fInput.getSourcedir());
        final File targetDir = new File(fInput.getTargetdir());

        final File[] files = sourceDir.listFiles();
        if (files == null) {
            return;
        }
        for (final File file : files) {
            if (file.isFile() == false) {
                continue;
            }

            byte[] fileData = BlancoFileUtil.file2Bytes(file);

            fileData = BlancoHtmlNormalizerUtil.normalize(fileData);

            final File targetFile = new File(targetDir.getAbsolutePath() + "/"
                    + file.getName());

            switch (BlancoFileUtil.bytes2FileIfNecessary(fileData, targetFile)) {
            case 1:
                progress("html: noromalize: create: " + file.getName());
                break;
            case 2:
                progress("html: noromalize: update: " + file.getName());
                break;
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean progress(final String argProgressMessage) {
        if (fInput != null && fInput.getVerbose()) {
            System.out.println(argProgressMessage);
        }
        return false;
    }
}
