/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.log4j;

import org.apache.log4j.helpers.QuietWriter;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.logging.log4j.status.StatusLogger;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;


/**
 * WriterAppender appends log events to a {@link Writer} or an
 * {@link OutputStream} depending on the user's choice.
 */
public class WriterAppender extends AppenderSkeleton {
    private static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger();

    /**
     * Immediate flush means that the underlying writer or output stream
     * will be flushed at the end of each append operation unless shouldFlush()
     * is overridden. Immediate
     * flush is slower but ensures that each append request is actually
     * written. If <code>immediateFlush</code> is set to
     * <code>false</code>, then there is a good chance that the last few
     * logs events are not actually written to persistent media if and
     * when the application crashes.
     *
     * <p>The <code>immediateFlush</code> variable is set to
     * <code>true</code> by default.
     */
    protected boolean immediateFlush = true;

    /**
     * The encoding to use when writing.  <p>The
     * <code>encoding</code> variable is set to <code>null</code> by
     * default which results in the utilization of the system's default
     * encoding.
     */
    protected String encoding;

    /**
     * This is the {@link QuietWriter quietWriter} where we will write
     * to.
     */
    protected QuietWriter qw;


    /**
     * This default constructor does nothing.
     */
    public WriterAppender() {
    }

    /**
     * Instantiate a WriterAppender and set the output destination to a
     * new {@link OutputStreamWriter} initialized with <code>os</code>
     * as its {@link OutputStream}.
     * @param layout The Layout.
     * @param os The OutputStream.
     */
    public WriterAppender(Layout layout, OutputStream os) {
        this(layout, new OutputStreamWriter(os));
    }

    /**
     * Instantiate a WriterAppender and set the output destination to <code>writer</code>.
     *
     * <p>The <code>writer</code> must have been previously opened by
     * the user.
     *
     * @param layout The Layout.
     * @param writer The Writer.
     */
    public WriterAppender(Layout layout, Writer writer) {
        this.layout = layout;
        this.setWriter(writer);
    }

    /**
     * Returns value of the <b>ImmediateFlush</b> option.
     * @return the value of the immediate flush setting.
     */
    public boolean getImmediateFlush() {
        return immediateFlush;
    }

    /**
     * If the <b>ImmediateFlush</b> option is set to
     * <code>true</code>, the appender will flush at the end of each
     * write. This is the default behavior. If the option is set to
     * <code>false</code>, then the underlying stream can defer writing
     * to physical medium to a later time.
     *
     * <p>Avoiding the flush operation at the end of each append results in
     * a performance gain of 10 to 20 percent. However, there is safety
     * tradeoff involved in skipping flushing. Indeed, when flushing is
     * skipped, then it is likely that the last few log events will not
     * be recorded on disk when the application exits. This is a high
     * price to pay even for a 20% performance gain.
     *
     * @param value the value to set the immediate flush setting to.
     */
    public void setImmediateFlush(boolean value) {
        immediateFlush = value;
    }

    /**
     * Does nothing.
     */
    public void activateOptions() {
    }


    /**
     * This method is called by the {@link AppenderSkeleton#doAppend}
     * method.
     *
     * <p>If the output stream exists and is writable then write a log
     * statement to the output stream. Otherwise, write a single warning
     * message to <code>System.err</code>.
     *
     * <p>The format of the output will depend on this appender's
     * layout.
     */
    public void append(LoggingEvent event) {

        // Reminder: the nesting of calls is:
        //
        //    doAppend()
        //      - check threshold
        //      - filter
        //      - append();
        //        - checkEntryConditions();
        //        - subAppend();

        if (!checkEntryConditions()) {
            return;
        }
        subAppend(event);
    }

    /**
     * This method determines if there is a sense in attempting to append.
     *
     * <p>It checks whether there is a set output target and also if
     * there is a set layout. If these checks fail, then the boolean
     * value <code>false</code> is returned.
     * @return true if appending is allowed, false otherwise.
     */
    protected boolean checkEntryConditions() {
        if (this.closed) {
            LOGGER.warn("Not allowed to write to a closed appender.");
            return false;
        }

        if (this.qw == null) {
            errorHandler.error("No output stream or file set for the appender named [" + name + "].");
            return false;
        }

        if (this.layout == null) {
            errorHandler.error("No layout set for the appender named [" + name + "].");
            return false;
        }
        return true;
    }


    /**
     * Close this appender instance. The underlying stream or writer is
     * also closed.
     *
     * <p>Closed appenders cannot be reused.
     *
     * @see #setWriter
     * @since 0.8.4
     */
    public
    synchronized void close() {
        if (this.closed) {
            return;
        }
        this.closed = true;
        writeFooter();
        reset();
    }

    /**
     * Close the underlying {@link Writer}.
     */
    protected void closeWriter() {
        if (qw != null) {
            try {
                qw.close();
            } catch (IOException e) {
                if (e instanceof InterruptedIOException) {
                    Thread.currentThread().interrupt();
                }
                // There is do need to invoke an error handler at this late
                // stage.
                LOGGER.error("Could not close " + qw, e);
            }
        }
    }

    /**
     * Returns an OutputStreamWriter when passed an OutputStream.  The
     * encoding used will depend on the value of the
     * <code>encoding</code> property.  If the encoding value is
     * specified incorrectly the writer will be opened using the default
     * system encoding (an error message will be printed to the LOGGER.
     * @param os The OutputStream.
     * @return The OutputStreamWriter.
     */
    protected OutputStreamWriter createWriter(OutputStream os) {
        OutputStreamWriter retval = null;

        String enc = getEncoding();
        if (enc != null) {
            try {
                retval = new OutputStreamWriter(os, enc);
            } catch (IOException e) {
                if (e instanceof InterruptedIOException) {
                    Thread.currentThread().interrupt();
                }
                LOGGER.warn("Error initializing output writer.");
                LOGGER.warn("Unsupported encoding?");
            }
        }
        if (retval == null) {
            retval = new OutputStreamWriter(os);
        }
        return retval;
    }

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String value) {
        encoding = value;
    }


    /**
     * Set the {@link ErrorHandler} for this WriterAppender and also the
     * underlying {@link QuietWriter} if any.
     */
    public synchronized void setErrorHandler(ErrorHandler eh) {
        if (eh == null) {
            LOGGER.warn("You have tried to set a null error-handler.");
        } else {
            this.errorHandler = eh;
            if (this.qw != null) {
                this.qw.setErrorHandler(eh);
            }
        }
    }

    /**
     * <p>Sets the Writer where the log output will go. The
     * specified Writer must be opened by the user and be
     * writable.
     *
     * <p>The <code>java.io.Writer</code> will be closed when the
     * appender instance is closed.
     *
     *
     * <p><b>WARNING:</b> Logging to an unopened Writer will fail.
     * <p>
     *
     * @param writer An already opened Writer.
     */
    public synchronized void setWriter(Writer writer) {
        reset();
        this.qw = new QuietWriter(writer, errorHandler);
        //this.tp = new TracerPrintWriter(qw);
        writeHeader();
    }


    /**
     * Actual writing occurs here.
     *
     * <p>Most subclasses of <code>WriterAppender</code> will need to
     * override this method.
     * @param event The event to log.
     *
     * @since 0.9.0
     */
    protected void subAppend(LoggingEvent event) {
        this.qw.write(this.layout.format(event));

        if (layout.ignoresThrowable()) {
            String[] s = event.getThrowableStrRep();
            if (s != null) {
                int len = s.length;
                for (int i = 0; i < len; i++) {
                    this.qw.write(s[i]);
                    this.qw.write(Layout.LINE_SEP);
                }
            }
        }

        if (shouldFlush(event)) {
            this.qw.flush();
        }
    }


    /**
     * The WriterAppender requires a layout. Hence, this method returns
     * <code>true</code>.
     */
    public boolean requiresLayout() {
        return true;
    }

    /**
     * Clear internal references to the writer and other variables.
     * <p>
     * Subclasses can override this method for an alternate closing
     * behavior.
     */
    protected void reset() {
        closeWriter();
        this.qw = null;
        //this.tp = null;
    }


    /**
     * Write a footer as produced by the embedded layout's {@link
     * Layout#getFooter} method.
     */
    protected void writeFooter() {
        if (layout != null) {
            String f = layout.getFooter();
            if (f != null && this.qw != null) {
                this.qw.write(f);
                this.qw.flush();
            }
        }
    }

    /**
     * Write a header as produced by the embedded layout's {@link
     * Layout#getHeader} method.
     */
    protected void writeHeader() {
        if (layout != null) {
            String h = layout.getHeader();
            if (h != null && this.qw != null) {
                this.qw.write(h);
            }
        }
    }

    /**
     * Determines whether the writer should be flushed after
     * this event is written.
     * @param event The event to log.
     * @return true if the writer should be flushed.
     *
     * @since 1.2.16
     */
    protected boolean shouldFlush(final LoggingEvent event) {
        return immediateFlush;
    }
}
