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

import java.util.ArrayList;
import java.util.Iterator;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractManager;
import org.apache.logging.log4j.core.appender.ManagerFactory;

public abstract class AbstractDatabaseManager extends AbstractManager {
   private final ArrayList<LogEvent> buffer;
   private final int bufferSize;
   private boolean running = false;

   protected AbstractDatabaseManager(String name, int bufferSize) {
      super(name);
      this.bufferSize = bufferSize;
      this.buffer = new ArrayList(bufferSize + 1);
   }

   protected abstract void startupInternal() throws Exception;

   public final synchronized void startup() {
      if (!this.isRunning()) {
         try {
            this.startupInternal();
            this.running = true;
         } catch (Exception var2) {
            LOGGER.error("Could not perform database startup operations using logging manager [{}].", this.getName(), var2);
         }
      }

   }

   protected abstract void shutdownInternal() throws Exception;

   public final synchronized void shutdown() {
      this.flush();
      if (this.isRunning()) {
         try {
            this.shutdownInternal();
         } catch (Exception var5) {
            LOGGER.warn("Error while performing database shutdown operations using logging manager [{}].", this.getName(), var5);
         } finally {
            this.running = false;
         }
      }

   }

   public final boolean isRunning() {
      return this.running;
   }

   protected abstract void connectAndStart();

   protected abstract void writeInternal(LogEvent var1);

   protected abstract void commitAndClose();

   public final synchronized void flush() {
      if (this.isRunning() && this.buffer.size() > 0) {
         this.connectAndStart();

         try {
            Iterator i$ = this.buffer.iterator();

            while(i$.hasNext()) {
               LogEvent event = (LogEvent)i$.next();
               this.writeInternal(event);
            }
         } finally {
            this.commitAndClose();
            this.buffer.clear();
         }
      }

   }

   public final synchronized void write(LogEvent event) {
      if (this.bufferSize > 0) {
         this.buffer.add(event);
         if (this.buffer.size() >= this.bufferSize || event.isEndOfBatch()) {
            this.flush();
         }
      } else {
         this.connectAndStart();

         try {
            this.writeInternal(event);
         } finally {
            this.commitAndClose();
         }
      }

   }

   public final void releaseSub() {
      this.shutdown();
   }

   public final String toString() {
      return this.getName();
   }

   protected static <M extends AbstractDatabaseManager, T extends AbstractDatabaseManager.AbstractFactoryData> M getManager(String name, T data, ManagerFactory<M, T> factory) {
      return (AbstractDatabaseManager)AbstractManager.getManager(name, factory, data);
   }

   protected abstract static class AbstractFactoryData {
      private final int bufferSize;

      protected AbstractFactoryData(int bufferSize) {
         this.bufferSize = bufferSize;
      }

      public int getBufferSize() {
         return this.bufferSize;
      }
   }
}
