/*
 * 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</null> 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}.
     */
    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.
     */
    public WriterAppender(Layout layout, Writer writer) {
        this.layout = layout;
        this.setWriter(writer);
    }

    /**
     * Returns value of the <b>ImmediateFlush</b> option.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     *
     * @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.
     *
     * @since 1.2.16
     */
    protected boolean shouldFlush(final LoggingEvent event) {
        return immediateFlush;
    }
}
