/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.log4j.net;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.plugins.Pauseable;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.Decoder;
import org.apache.log4j.spi.LoggingEvent;


/**
 *  Receive LoggingEvents encoded with an XMLLayout, convert the XML data to a
 *  LoggingEvent and post the LoggingEvent.
 *
 *  @author Scott Deboy &lt;sdeboy@apache.org&gt;
 *
 */
public class UDPReceiver extends Receiver implements PortBased, Pauseable {
  private static final int PACKET_LENGTH = 16384;
  private UDPReceiverThread receiverThread;
  private String encoding;

  //default to log4j xml decoder
  private String decoder = "org.apache.log4j.xml.XMLDecoder";
  private Decoder decoderImpl;
  protected boolean paused;
  private transient boolean closed = false;
  private int port;
  private DatagramSocket socket;
  UDPHandlerThread handlerThread;
  private boolean advertiseViaMulticastDNS;
  private ZeroConfSupport zeroConf;

  /**
   * The MulticastDNS zone advertised by a UDPReceiver
   */
  public static final String ZONE = "_log4j_xml_udp_receiver.local.";


    public int getPort() {
    return port;
  }

  public void setPort(int port) {
    this.port = port;
  }

  /**
   * The <b>Encoding</b> option specifies how the bytes are encoded.  If this 
   * option is not specified, the system encoding will be used.
   * */
  public void setEncoding(String encoding) {
    this.encoding = encoding;
  }

  /**
   * Returns value of the <b>Encoding</b> option.
   */
  public String getEncoding() {
    return encoding;
  }

  public String getDecoder() {
    return decoder;
  }

  public void setDecoder(String decoder) {
    this.decoder = decoder;
  }

  public boolean isPaused() {
    return paused;
  }

  public void setPaused(boolean b) {
    paused = b;
  }

  public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
    this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
  }

  public boolean isAdvertiseViaMulticastDNS() {
    return advertiseViaMulticastDNS;
  }

  public synchronized void shutdown() {
    if(closed == true) {
      return;
    }
    closed = true;
    active = false;
    // Closing the datagram socket will unblock the UDPReceiverThread if it is
    // was waiting to receive data from the socket.
    if (socket != null) {
    	socket.close();
    }

    if (advertiseViaMulticastDNS) {
      zeroConf.unadvertise();
    }
      
    try {
      if(handlerThread != null) {
      	handlerThread.close();
        handlerThread.join();
      }
      if(receiverThread != null) {
        receiverThread.join();
      }
    } catch(InterruptedException ie) {
    }
  }

  /**
    Returns true if this receiver is active. */
//  public synchronized boolean isActive() {
//    return isActive;
//}

  public void activateOptions() {
    try {
      Class c = Class.forName(decoder);
      Object o = c.newInstance();

      if (o instanceof Decoder) {
        this.decoderImpl = (Decoder) o;
      }
    } catch (ClassNotFoundException cnfe) {
      getLogger().warn("Unable to find decoder", cnfe);
    } catch (IllegalAccessException | InstantiationException iae) {
      getLogger().warn("Could not construct decoder", iae);
    }

      try {
      socket = new DatagramSocket(port);
      receiverThread = new UDPReceiverThread();
      receiverThread.start();
      handlerThread = new UDPHandlerThread();
      handlerThread.start();
      if (advertiseViaMulticastDNS) {
        zeroConf = new ZeroConfSupport(ZONE, port, getName());
        zeroConf.advertise();
      }
      active = true;
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }

  class UDPHandlerThread extends Thread {
    private final List<String> list = new ArrayList<>();

    public UDPHandlerThread() {
      setDaemon(true);
    }

    public void append(String data) {
      synchronized (list) {
        list.add(data);
        list.notify();
      }
    }

    /**
     * Allow the UDPHandlerThread to wakeup and exit gracefully.
     */
    void close() {
      synchronized(list) {
      	list.notify();
      }
    }

    public void run() {
      ArrayList<String> list2 = new ArrayList<>();

      while (!UDPReceiver.this.closed) {
        synchronized (list) {
          try {
            while (!UDPReceiver.this.closed && list.size() == 0) {
              list.wait(300);
            }

            if (list.size() > 0) {
              list2.addAll(list);
              list.clear();
            }
          } catch (InterruptedException ie) {
          }
        }

        if (list2.size() > 0) {

            for (Object aList2 : list2) {
                String data = (String) aList2;
                List<LoggingEvent> v = decoderImpl.decodeEvents(data);

                if (v != null) {

                    for (Object aV : v) {
                        if (!isPaused()) {
                            doPost((LoggingEvent) aV);
                        }
                    }
                }
            }

          list2.clear();
        } else {
          try {
            synchronized (this) {
              wait(1000);
            }
          } catch (InterruptedException ie) {
          }
        }
      } // while
      getLogger().debug(UDPReceiver.this.getName()+ "'s handler thread is exiting");
    } // run
  } // UDPHandlerThread

  class UDPReceiverThread extends Thread {
    public UDPReceiverThread() {
      setDaemon(true);
    }
    
    public void run() {
      byte[] b = new byte[PACKET_LENGTH];
      DatagramPacket p = new DatagramPacket(b, b.length);

      while (!UDPReceiver.this.closed) {
        try {
          socket.receive(p);
          
          //this string constructor which accepts a charset throws an exception if it is 
          //null
          if (encoding == null) {
            handlerThread.append(
              new String(p.getData(), 0, p.getLength()));
          } else {
            handlerThread.append(
              new String(p.getData(), 0, p.getLength(), encoding));
          }
        } catch (SocketException se) {
          //disconnected
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
      }

      //LogLog.debug(UDPReceiver.this.getName() + "'s thread is ending.");
    }
  }
}
