package org.apache.logging.log4j.core.net.server;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OptionalDataException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import org.apache.logging.log4j.core.config.ConfigurationFactory;

public class UdpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
   private final DatagramSocket datagramSocket;
   private final int maxBufferSize = 67584;

   public static UdpSocketServer<InputStream> createJsonSocketServer(int port) throws IOException {
      return new UdpSocketServer(port, new JsonInputStreamLogEventBridge());
   }

   public static UdpSocketServer<ObjectInputStream> createSerializedSocketServer(int port) throws IOException {
      return new UdpSocketServer(port, new ObjectInputStreamLogEventBridge());
   }

   public static UdpSocketServer<InputStream> createXmlSocketServer(int port) throws IOException {
      return new UdpSocketServer(port, new XmlInputStreamLogEventBridge());
   }

   public static void main(String[] args) throws Exception {
      if (args.length >= 1 && args.length <= 2) {
         int port = Integer.parseInt(args[0]);
         if (port > 0 && port < 65534) {
            if (args.length == 2 && args[1].length() > 0) {
               ConfigurationFactory.setConfigurationFactory(new AbstractSocketServer.ServerConfigurationFactory(args[1]));
            }

            UdpSocketServer<ObjectInputStream> socketServer = createSerializedSocketServer(port);
            Thread server = new Thread(socketServer);
            server.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

            String line;
            do {
               line = reader.readLine();
            } while(line != null && !line.equalsIgnoreCase("Quit") && !line.equalsIgnoreCase("Stop") && !line.equalsIgnoreCase("Exit"));

            socketServer.shutdown();
            server.join();
         } else {
            System.err.println("Invalid port number");
            printUsage();
         }
      } else {
         System.err.println("Incorrect number of arguments");
         printUsage();
      }
   }

   private static void printUsage() {
      System.out.println("Usage: ServerSocket port configFilePath");
   }

   public UdpSocketServer(int port, LogEventBridge<T> logEventInput) throws IOException {
      super(port, logEventInput);
      this.datagramSocket = new DatagramSocket(port);
   }

   public void run() {
      while(this.isActive()) {
         if (this.datagramSocket.isClosed()) {
            return;
         }

         try {
            byte[] buf = new byte[67584];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            this.datagramSocket.receive(packet);
            ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength());
            this.logEventInput.logEvents(this.logEventInput.wrapStream(bais), this);
         } catch (OptionalDataException var4) {
            if (this.datagramSocket.isClosed()) {
               return;
            }

            this.logger.error((String)("OptionalDataException eof=" + var4.eof + " length=" + var4.length), (Throwable)var4);
         } catch (EOFException var5) {
            if (this.datagramSocket.isClosed()) {
               return;
            }

            this.logger.info("EOF encountered");
         } catch (IOException var6) {
            if (this.datagramSocket.isClosed()) {
               return;
            }

            this.logger.error((String)"Exception encountered on accept. Ignoring. Stack Trace :", (Throwable)var6);
         }
      }

   }

   public void shutdown() {
      this.setActive(false);
      Thread.currentThread().interrupt();
      this.datagramSocket.close();
   }
}
