/*
 * Copyright 2002,2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.catalina.ant;


import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Redirector;
import org.apache.tools.ant.types.RedirectorElement;


/**
 * Abstract base class to add output redirection support for Catalina
 * Ant tasks. These tasks require Ant 1.5 or later.
 * <br>
 * <strong>WARNING:</strong> due to depends chain, Ant could call a Task 
 * more than once and this can affect the output redirection when configured.
 * If you are collecting the output in a property, it will collect the output
 * of only the first run, since Ant properties are immutable and once created
 * they cannot be changed.
 * <br>
 * If you are collecting output in a file the file will be overwritten with the
 * output of the last run, unless you set append="true", in which case each run 
 * will append it's output to the file.
 * 
 *
 * @author Gabriele Garuglieri
 * @version $Revision$ $Date$
 * @since 5.5
 */

public abstract class BaseRedirectorHelperTask extends Task {

    // ------------------------------------------------------------- Properties

    /** Redirector helper */
    protected Redirector redirector = new Redirector(this);
    //protected Redirector redirector = null;
    /** Redirector element for this task */
    protected RedirectorElement redirectorElement = null;
    /** The stream for info output */
    protected OutputStream redirectOutStream = null;
    /** The stream for error output */
    protected OutputStream redirectErrStream = null;
    /** The print stream for info output */
    PrintStream redirectOutPrintStream = null;
    /** The print stream for error output */
    PrintStream redirectErrPrintStream = null;
        
   /**
     * Whether to fail (with a BuildException) if
     * ManagerServlet returns an error. The default behavior is
     * to do so.
     * <b>
     * This flag does not control parameters checking. If the task is called
     * with wrong or invalid parameters, it will throw BuildException
     * independently from the setting of this flag.
     */    
    protected boolean failOnError = true;
    
    /** 
      * <code>true</code> true when output redirection is requested for this task .
      * Default is to log on Ant log.
      */    
    protected boolean redirectOutput = false;
 
    /** 
      * will be set to <code>true</code> when the configuration of the Redirector is
      * complete.
      */    
    protected boolean redirectorConfigured = false;

    /** 
     * Flag which indicates that, if redirected, output should also be 
     * always sent to the log. Default is that otput is sent only to
     * redirected streams.
     */
    protected boolean alwaysLog = false;

    /**
     * Whether to fail (with a BuildException) if
     * ManagerServlet returns an error.  The default behavior is
     * to do so.
     */
    public void setFailonerror(boolean fail) {
        failOnError = fail;
    }

    /**
     * Returns the value of the failOnError
     * property.
     */
    public boolean isFailOnError() {
      return failOnError;
    }
        

    /**
     * File the output of the task is redirected to.
     *
     * @param out name of the output file
     */
    public void setOutput(File out) {
        redirector.setOutput(out);
        redirectOutput = true;
    }

    /**
     * File the error output of the task is redirected to.
     *
     * @param error name of the error file
     *
     */
    public void setError(File error) {
        redirector.setError(error);
        redirectOutput = true;
    }

    /**
     * Controls whether error output is logged. This is only useful
     * when output is being redirected and error output is desired in the
     * Ant log
     *
     * @param logError if true the standard error is sent to the Ant log system
     *        and not sent to output stream.
     */
    public void setLogError(boolean logError) {
        redirector.setLogError(logError);
        redirectOutput = true;
    }

    /**
     * Property name whose value should be set to the output of
     * the task.
     *
     * @param outputProperty property name
     *
     */
    public void setOutputproperty(String outputProperty) {
        redirector.setOutputProperty(outputProperty);
        redirectOutput = true;
    }

    /**
     * Property name whose value should be set to the error of
     * the task..
     *
     * @param errorProperty property name
     *
     */
    public void setErrorProperty(String errorProperty) {
        redirector.setErrorProperty(errorProperty);
        redirectOutput = true;
    }

    /**
     * If true, append output to existing file.
     *
     * @param append if true, append output to existing file
     *
     */
    public void setAppend(boolean append) {
        redirector.setAppend(append);
        redirectOutput = true;
    }

    /**
     * If true, (error and non-error) output will be redirected
     * as specified while being sent to Ant's logging mechanism as if no
     * redirection had taken place.  Defaults to false.
     * <br>
     * Actually handled internally, with Ant 1.6.3 it will be handled by
     * the <code>Redirector</code> itself.
     * @param alwaysLog <code>boolean</code>
     */
    public void setAlwaysLog(boolean alwaysLog) {
        this.alwaysLog = alwaysLog;
        //redirector.setAlwaysLog(alwaysLog);
        redirectOutput = true;
    }

    /**
     * Whether output and error files should be created even when empty.
     * Defaults to true.
     * @param createEmptyFiles <CODE>boolean</CODE>.
     */
    public void setCreateEmptyFiles(boolean createEmptyFiles) {
        redirector.setCreateEmptyFiles(createEmptyFiles);
        redirectOutput = true;
    }

    /**
     * Add a <CODE>RedirectorElement</CODE> to this task.
     * @param redirectorElement   <CODE>RedirectorElement</CODE>.
     */
    public void addConfiguredRedirector(RedirectorElement redirectorElement) {
        if (this.redirectorElement != null) {
            throw new BuildException("Cannot have > 1 nested <redirector>s");
        } else {
            this.redirectorElement = redirectorElement;
        }
    }

    /**
     * Set up properties on the Redirector from RedirectorElement if present.
     */
    private void configureRedirector() {
        if (redirectorElement != null) {
            redirectorElement.configure(redirector);
            redirectOutput = true;
        }
        /*
         * Due to depends chain, Ant could call the Task more than once,
         * this is to prevent that we attempt to configure uselessly
         * more than once the Redirector.
         */
        redirectorConfigured = true;
    }

    /**
     * Set up properties on the Redirector and create output streams.
     */
    protected void openRedirector() {
        if (! redirectorConfigured) {
            configureRedirector();
        }
        if (redirectOutput) {
            redirector.createStreams();
            redirectOutStream = redirector.getOutputStream();
            redirectOutPrintStream = new PrintStream(redirectOutStream);
            redirectErrStream = redirector.getErrorStream();
            redirectErrPrintStream = new PrintStream(redirectErrStream);
        }
   }

    /**
     * Ask redirector to close all the streams. It is necessary to call this method
     * before leaving the Task to have the Streams flush their contents. If you are 
     * collecting output in a property, it will be created only if this method is
     * called, otherwise you'll find it unset.
     */
    protected void closeRedirector() {
        try {
            if (redirectOutput) {
                redirector.complete();
            }
        } catch (IOException ioe) {
            log("Error closing redirector: "
                + ioe.getMessage(), Project.MSG_ERR);
        }
        /*
         * Due to depends chain, Ant could call the Task more than once,
         * this is to prevent that we attempt to reuse the previuosly 
         * closed Streams.
         */
        redirectOutStream = null;
        redirectOutPrintStream = null;
        redirectErrStream = null;
        redirectErrPrintStream = null;
    }
    
    /**
     * Handles output with the INFO priority.
     *
     * @param output The output to log. Should not be <code>null</code>.
     */
    protected void handleOutput(String output) {
        if (redirectOutput) {
            if (redirectOutPrintStream == null) {
                openRedirector();
            }
            redirectOutPrintStream.println(output);
            if (alwaysLog) {
                log(output, Project.MSG_INFO);
            }
        } else { 
            log(output, Project.MSG_INFO);
        }
    }

    /**
     * Handles output with the INFO priority and flushes the stream.
     *
     * @param output The output to log. Should not be <code>null</code>.
     *
     */
    protected void handleFlush(String output) {
        handleOutput(output);
        redirectOutPrintStream.flush();
    }

    /**
     * Handles error output with the ERR priority.
     *
     * @param output The error output to log. Should not be <code>null</code>.
     */
    protected void handleErrorOutput(String output) {
        if (redirectOutput) {
            if (redirectErrPrintStream == null) {
                openRedirector();
            }
            redirectErrPrintStream.println(output);
            if (alwaysLog) {
                log(output, Project.MSG_ERR);
            }
        } else { 
            log(output, Project.MSG_ERR);
        }
    }

    /**
     * Handles error output with the ERR priority and flushes the stream.
     *
     * @param output The error output to log. Should not be <code>null</code>.
     *
     */
    protected void handleErrorFlush(String output) {
        handleErrorOutput(output);
        redirectErrPrintStream.flush();
    }
  
    /**
     * Handles output with ERR priority to error stream and all other
     * pritorities to output stream.
     *
     * @param output The output to log. Should not be <code>null</code>.
     */
    protected void handleOutput(String output, int priority) {
        if (priority == Project.MSG_ERR) {
            handleErrorOutput(output);
        } else {
            handleOutput(output);
        }
    }
  
    /**
     * Handles output with ERR priority to error stream and all other
     * pritorities to output stream, then flushes the stream.
     *
     * @param output The output to log. Should not be <code>null</code>.
     */
    protected void handleFlush(String output, int priority) {
        if (priority == Project.MSG_ERR) {
            handleErrorFlush(output);
        } else {
            handleFlush(output);
        }
    }

}
