/*
 * 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 org.apache.log4j.plugins.Pauseable;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Vector;


/**
 * XMLSocketReceiver receives a remote logging event via XML on a configured
 * socket and "posts" it to a LoggerRepository as if the event were
 * generated locally. This class is designed to receive events from
 * the XMLSocketAppender class (or classes that send compatible events).
 * <p>
 * This receiver supports log files created using log4j's XMLLayout, as well as java.util.logging
 * XMLFormatter (via the org.apache.log4j.spi.Decoder interface).
 * <p>
 * By default, log4j's XMLLayout is supported (no need to specify a decoder in that case).
 * <p>
 * To configure this receiver to support java.util.logging's XMLFormatter, specify a 'decoder' param
 * of org.apache.log4j.xml.UtilLoggingXMLDecoder.
 * <p>
 * Once the event has been "posted", it will be handled by the
 * appenders currently configured in the LoggerRespository.
 *
 * @author Mark Womack
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 */
public class XMLSocketReceiver extends Receiver implements Runnable, PortBased, Pauseable {
    private boolean paused;
    //default to log4j xml decoder
    protected String decoder = "org.apache.log4j.xml.XMLDecoder";
    private ServerSocket serverSocket;
    private List<Socket> socketList = new Vector<>();
    private Thread rThread;
    public static final int DEFAULT_PORT = 4448;
    protected int port = DEFAULT_PORT;
    private boolean advertiseViaMulticastDNS;
    private ZeroConfSupport zeroConf;

    /**
     * The MulticastDNS zone advertised by an XMLSocketReceiver
     */
    public static final String ZONE = "_log4j_xml_tcpaccept_receiver.local.";

    /*
     * Log4j doesn't provide an XMLSocketAppender, but the MulticastDNS zone that should be advertised by one is:
     * _log4j_xml_tcpconnect_appender.local.
     */

    public XMLSocketReceiver() {
    }

    public XMLSocketReceiver(int _port) {
        port = _port;
    }

    public XMLSocketReceiver(int _port, LoggerRepository _repository) {
        port = _port;
        repository = _repository;
    }

    /**
     * Get the port to receive logging events on.
     */
    public int getPort() {
        return port;
    }

    /**
     * Set the port to receive logging events on.
     */
    public void setPort(int _port) {
        port = _port;
    }

    public String getDecoder() {
        return decoder;
    }

    /**
     * Specify the class name implementing org.apache.log4j.spi.Decoder that can process the file.
     */
    public void setDecoder(String _decoder) {
        decoder = _decoder;
    }

    public boolean isPaused() {
        return paused;
    }

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

    /**
     * Returns true if the receiver is the same class and they are
     * configured for the same properties, and super class also considers
     * them to be equivalent. This is used by PluginRegistry when determining
     * if the a similarly configured receiver is being started.
     *
     * @param testPlugin The plugin to test equivalency against.
     * @return boolean True if the testPlugin is equivalent to this plugin.
     */
    public boolean isEquivalent(Plugin testPlugin) {
        if ((testPlugin != null) && testPlugin instanceof XMLSocketReceiver) {
            XMLSocketReceiver sReceiver = (XMLSocketReceiver) testPlugin;

            return (port == sReceiver.getPort() && super.isEquivalent(testPlugin));
        }

        return false;
    }

    public int hashCode() {

        int result = 37 * (repository != null ? repository.hashCode() : 0);
        result = result * 37 + port;
        return (result * 37 + (getName() != null ? getName().hashCode() : 0));
    }

    /**
     * Sets the flag to indicate if receiver is active or not.
     *
     * @param b new value
     */
    protected synchronized void setActive(final boolean b) {
        active = b;
    }

    /**
     * Starts the XMLSocketReceiver with the current options.
     */
    public void activateOptions() {
        if (!isActive()) {
            rThread = new Thread(this);
            rThread.setDaemon(true);
            rThread.start();

            if (advertiseViaMulticastDNS) {
                zeroConf = new ZeroConfSupport(ZONE, port, getName());
                zeroConf.advertise();
            }

            active = true;
        }
    }

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

    public boolean isAdvertiseViaMulticastDNS() {
        return advertiseViaMulticastDNS;
    }

    /**
     * Called when the receiver should be stopped. Closes the
     * server socket and all of the open sockets.
     */
    public synchronized void shutdown() {
        // mark this as no longer running
        active = false;

        if (rThread != null) {
            rThread.interrupt();
            rThread = null;
        }
        doShutdown();
    }

    /**
     * Does the actual shutting down by closing the server socket
     * and any connected sockets that have been created.
     */
    private synchronized void doShutdown() {
        active = false;

        getLogger().debug("{} doShutdown called", getName());

        // close the server socket
        closeServerSocket();

        // close all of the accepted sockets
        closeAllAcceptedSockets();

        if (advertiseViaMulticastDNS) {
            zeroConf.unadvertise();
        }
    }

    /**
     * Closes the server socket, if created.
     */
    private void closeServerSocket() {
        getLogger().debug("{} closing server socket", getName());

        try {
            if (serverSocket != null) {
                serverSocket.close();
            }
        } catch (Exception e) {
            // ignore for now
        }

        serverSocket = null;
    }

    /**
     * Closes all the connected sockets in the List.
     */
    private synchronized void closeAllAcceptedSockets() {
        for (Object aSocketList : socketList) {
            try {
                ((Socket) aSocketList).close();
            } catch (Exception e) {
                // ignore for now
            }
        }

        // clear member variables
        socketList.clear();
    }

    /**
     * Loop, accepting new socket connections.
     */
    public void run() {
        /**
         * Ensure we start fresh.
         */
        getLogger().debug("performing socket cleanup prior to entering loop for {}", name);
        closeServerSocket();
        closeAllAcceptedSockets();
        getLogger().debug("socket cleanup complete for {}", name);
        active = true;

        // start the server socket
        try {
            serverSocket = new ServerSocket(port);
        } catch (Exception e) {
            getLogger().error(
                "error starting XMLSocketReceiver (" + this.getName()
                    + "), receiver did not start", e);
            active = false;
            doShutdown();

            return;
        }

        Socket socket = null;

        try {
            getLogger().debug("in run-about to enter while isactiveloop");

            active = true;

            while (!rThread.isInterrupted()) {
                // if we have a socket, start watching it
                if (socket != null) {
                    getLogger().debug("socket not null - creating and starting socketnode");
                    socketList.add(socket);

                    XMLSocketNode node = new XMLSocketNode(decoder, socket, this);
                    node.setLoggerRepository(this.repository);
                    new Thread(node).start();
                }

                getLogger().debug("waiting to accept socket");

                // wait for a socket to open, then loop to start it
                socket = serverSocket.accept();
                getLogger().debug("accepted socket");
            }

            // socket not watched because we a no longer running
            // so close it now.
            if (socket != null) {
                socket.close();
            }
        } catch (Exception e) {
            getLogger().warn(
                "socket server disconnected, stopping");
        }
    }

    /* (non-Javadoc)
     * @see org.apache.log4j.plugins.Receiver#doPost(org.apache.log4j.spi.LoggingEvent)
     */
    public void doPost(LoggingEvent event) {
        if (!isPaused()) {
            super.doPost(event);
        }
    }


}
