package org.apache.logging.log4j.core.appender;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.logging.log4j.core.Layout;

public class OutputStreamManager extends AbstractManager {
   private volatile OutputStream os;
   protected final Layout<?> layout;

   protected OutputStreamManager(OutputStream os, String streamName, Layout<?> layout) {
      super(streamName);
      this.os = os;
      this.layout = layout;
      if (layout != null) {
         byte[] header = layout.getHeader();
         if (header != null) {
            try {
               this.os.write(header, 0, header.length);
            } catch (IOException var6) {
               LOGGER.error((String)"Unable to write header", (Throwable)var6);
            }
         }
      }

   }

   public static <T> OutputStreamManager getManager(String name, T data, ManagerFactory<? extends OutputStreamManager, T> factory) {
      return (OutputStreamManager)AbstractManager.getManager(name, factory, data);
   }

   public void releaseSub() {
      this.writeFooter();
      this.close();
   }

   protected void writeFooter() {
      if (this.layout != null) {
         byte[] footer = this.layout.getFooter();
         if (footer != null) {
            this.write(footer);
         }

      }
   }

   public boolean isOpen() {
      return this.getCount() > 0;
   }

   protected OutputStream getOutputStream() {
      return this.os;
   }

   protected void setOutputStream(OutputStream os) {
      byte[] header = this.layout.getHeader();
      if (header != null) {
         try {
            os.write(header, 0, header.length);
            this.os = os;
         } catch (IOException var4) {
            LOGGER.error((String)"Unable to write header", (Throwable)var4);
         }
      } else {
         this.os = os;
      }

   }

   protected synchronized void write(byte[] bytes, int offset, int length) {
      try {
         this.os.write(bytes, offset, length);
      } catch (IOException var6) {
         String msg = "Error writing to stream " + this.getName();
         throw new AppenderLoggingException(msg, var6);
      }
   }

   protected void write(byte[] bytes) {
      this.write(bytes, 0, bytes.length);
   }

   protected synchronized void close() {
      OutputStream stream = this.os;
      if (stream != System.out && stream != System.err) {
         try {
            stream.close();
         } catch (IOException var3) {
            LOGGER.error("Unable to close stream " + this.getName() + ". " + var3);
         }

      }
   }

   public synchronized void flush() {
      try {
         this.os.flush();
      } catch (IOException var3) {
         String msg = "Error flushing stream " + this.getName();
         throw new AppenderLoggingException(msg, var3);
      }
   }
}
