/*
 * Decompiled with CFR 0.152.
 */
package org.apache.logging.log4j.core.appender;

import java.io.Serializable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.appender.AbstractManager;
import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.appender.OutputStreamManager;

public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager>
extends AbstractAppender {
    protected final boolean immediateFlush;
    private final M manager;
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock readLock = this.rwLock.readLock();

    protected AbstractOutputStreamAppender(String name, Layout<? extends Serializable> layout, Filter filter, boolean ignoreExceptions, boolean immediateFlush, M manager) {
        super(name, filter, layout, ignoreExceptions);
        this.manager = manager;
        this.immediateFlush = immediateFlush;
    }

    public M getManager() {
        return this.manager;
    }

    @Override
    public void start() {
        if (this.getLayout() == null) {
            LOGGER.error("No layout set for the appender named [" + this.getName() + "].");
        }
        if (this.manager == null) {
            LOGGER.error("No OutputStreamManager set for the appender named [" + this.getName() + "].");
        }
        super.start();
    }

    @Override
    public void stop() {
        super.stop();
        ((AbstractManager)this.manager).release();
    }

    @Override
    public void append(LogEvent event) {
        this.readLock.lock();
        try {
            byte[] bytes = this.getLayout().toByteArray(event);
            if (bytes.length > 0) {
                ((OutputStreamManager)this.manager).write(bytes);
                if (this.immediateFlush || event.isEndOfBatch()) {
                    ((OutputStreamManager)this.manager).flush();
                }
            }
        }
        catch (AppenderLoggingException ex) {
            this.error("Unable to write to stream " + ((AbstractManager)this.manager).getName() + " for appender " + this.getName());
            throw ex;
        }
        finally {
            this.readLock.unlock();
        }
    }
}
