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

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.concurrent.Semaphore;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.FileManager;
import org.apache.logging.log4j.core.appender.ManagerFactory;
import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction;
import org.apache.logging.log4j.core.appender.rolling.action.Action;

public class RollingFileManager extends FileManager {
   private static RollingFileManager.RollingFileManagerFactory factory = new RollingFileManager.RollingFileManagerFactory();
   private long size;
   private long initialTime;
   private final PatternProcessor patternProcessor;
   private final Semaphore semaphore = new Semaphore(1);
   private final TriggeringPolicy triggeringPolicy;
   private final RolloverStrategy rolloverStrategy;

   protected RollingFileManager(String fileName, String pattern, OutputStream os, boolean append, long size, long time, TriggeringPolicy triggeringPolicy, RolloverStrategy rolloverStrategy, String advertiseURI, Layout<? extends Serializable> layout, int bufferSize) {
      super(fileName, os, append, false, advertiseURI, layout, bufferSize);
      this.size = size;
      this.initialTime = time;
      this.triggeringPolicy = triggeringPolicy;
      this.rolloverStrategy = rolloverStrategy;
      this.patternProcessor = new PatternProcessor(pattern);
      triggeringPolicy.initialize(this);
   }

   public static RollingFileManager getFileManager(String fileName, String pattern, boolean append, boolean bufferedIO, TriggeringPolicy policy, RolloverStrategy strategy, String advertiseURI, Layout<? extends Serializable> layout, int bufferSize) {
      return (RollingFileManager)getManager(fileName, new RollingFileManager.FactoryData(pattern, append, bufferedIO, policy, strategy, advertiseURI, layout, bufferSize), factory);
   }

   protected synchronized void write(byte[] bytes, int offset, int length) {
      this.size += (long)length;
      super.write(bytes, offset, length);
   }

   public long getFileSize() {
      return this.size;
   }

   public long getFileTime() {
      return this.initialTime;
   }

   public synchronized void checkRollover(LogEvent event) {
      if (this.triggeringPolicy.isTriggeringEvent(event) && this.rollover(this.rolloverStrategy)) {
         try {
            this.size = 0L;
            this.initialTime = System.currentTimeMillis();
            this.createFileAfterRollover();
         } catch (IOException var3) {
            LOGGER.error("FileManager (" + this.getFileName() + ") " + var3);
         }
      }

   }

   protected void createFileAfterRollover() throws IOException {
      OutputStream os = new FileOutputStream(this.getFileName(), this.isAppend());
      if (this.getBufferSize() > 0) {
         this.setOutputStream(new BufferedOutputStream(os, this.getBufferSize()));
      } else {
         this.setOutputStream(os);
      }

   }

   public PatternProcessor getPatternProcessor() {
      return this.patternProcessor;
   }

   public TriggeringPolicy getTriggeringPolicy() {
      return this.triggeringPolicy;
   }

   public RolloverStrategy getRolloverStrategy() {
      return this.rolloverStrategy;
   }

   private boolean rollover(RolloverStrategy strategy) {
      try {
         this.semaphore.acquire();
      } catch (InterruptedException var11) {
         LOGGER.error((String)"Thread interrupted while attempting to check rollover", (Throwable)var11);
         return false;
      }

      boolean success = false;
      Thread thread = null;

      boolean var5;
      try {
         RolloverDescription descriptor = strategy.rollover(this);
         if (descriptor == null) {
            var5 = false;
            return var5;
         }

         this.writeFooter();
         this.close();
         if (descriptor.getSynchronous() != null) {
            LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());

            try {
               success = descriptor.getSynchronous().execute();
            } catch (Exception var10) {
               LOGGER.error((String)"Error in synchronous task", (Throwable)var10);
            }
         }

         if (success && descriptor.getAsynchronous() != null) {
            LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
            thread = new Thread(new RollingFileManager.AsyncAction(descriptor.getAsynchronous(), this));
            thread.start();
         }

         var5 = true;
      } finally {
         if (thread == null || !thread.isAlive()) {
            this.semaphore.release();
         }

      }

      return var5;
   }

   private static class RollingFileManagerFactory implements ManagerFactory<RollingFileManager, RollingFileManager.FactoryData> {
      private RollingFileManagerFactory() {
      }

      public RollingFileManager createManager(String name, RollingFileManager.FactoryData data) {
         File file = new File(name);
         File parent = file.getParentFile();
         if (null != parent && !parent.exists()) {
            parent.mkdirs();
         }

         try {
            file.createNewFile();
         } catch (IOException var12) {
            RollingFileManager.LOGGER.error((String)("Unable to create file " + name), (Throwable)var12);
            return null;
         }

         long size = data.append ? file.length() : 0L;

         try {
            OutputStream os = new FileOutputStream(name, data.append);
            int bufferSize = data.bufferSize;
            if (data.bufferedIO) {
               os = new BufferedOutputStream((OutputStream)os, bufferSize);
            } else {
               bufferSize = -1;
            }

            long time = file.lastModified();
            return new RollingFileManager(name, data.pattern, (OutputStream)os, data.append, size, time, data.policy, data.strategy, data.advertiseURI, data.layout, bufferSize);
         } catch (FileNotFoundException var11) {
            RollingFileManager.LOGGER.error("FileManager (" + name + ") " + var11);
            return null;
         }
      }

      // $FF: synthetic method
      RollingFileManagerFactory(Object x0) {
         this();
      }
   }

   private static class FactoryData {
      private final String pattern;
      private final boolean append;
      private final boolean bufferedIO;
      private final int bufferSize;
      private final TriggeringPolicy policy;
      private final RolloverStrategy strategy;
      private final String advertiseURI;
      private final Layout<? extends Serializable> layout;

      public FactoryData(String pattern, boolean append, boolean bufferedIO, TriggeringPolicy policy, RolloverStrategy strategy, String advertiseURI, Layout<? extends Serializable> layout, int bufferSize) {
         this.pattern = pattern;
         this.append = append;
         this.bufferedIO = bufferedIO;
         this.bufferSize = bufferSize;
         this.policy = policy;
         this.strategy = strategy;
         this.advertiseURI = advertiseURI;
         this.layout = layout;
      }
   }

   private static class AsyncAction extends AbstractAction {
      private final Action action;
      private final RollingFileManager manager;

      public AsyncAction(Action act, RollingFileManager manager) {
         this.action = act;
         this.manager = manager;
      }

      public boolean execute() throws IOException {
         boolean var1;
         try {
            var1 = this.action.execute();
         } finally {
            this.manager.semaphore.release();
         }

         return var1;
      }

      public void close() {
         this.action.close();
      }

      public boolean isComplete() {
         return this.action.isComplete();
      }
   }
}
