/*
 * 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.Logger;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.ComponentBase;
import org.apache.log4j.spi.Decoder;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.List;


/**
 * Read {@link LoggingEvent} objects sent from a remote client using XML over
 * Sockets (TCP). These logging events are logged according to local
 * policy, as if they were generated locally.
 * <p>
 * <p>For example, the socket node might decide to log events to a
 * local file and also resent them to a second socket node.
 *
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;;
 * @since 0.8.4
 */
public class XMLSocketNode extends ComponentBase implements Runnable {
    Socket socket;
    Receiver receiver;
    Decoder decoder;
    SocketNodeEventListener listener;

    /**
     * Constructor for socket and logger repository.
     */
    public XMLSocketNode(
        String decoder, Socket socket, LoggerRepository hierarchy) {
        this.repository = hierarchy;
        try {
            Class c = Class.forName(decoder);
            Object o = c.newInstance();

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

        this.socket = socket;
    }

    /**
     * Constructor for socket and reciever.
     */
    public XMLSocketNode(String decoder, Socket socket, Receiver receiver) {
        try {
            Class c = Class.forName(decoder);
            Object o = c.newInstance();

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

        this.socket = socket;
        this.receiver = receiver;
    }

    /**
     * Set the event listener on this node.
     */
    public void setListener(SocketNodeEventListener _listener) {
        listener = _listener;
    }

    public void run() {
        Logger remoteLogger;
        Exception listenerException = null;
        InputStream is;

        if ((this.receiver == null) || (this.decoder == null)) {
            listenerException =
                new Exception(
                    "No receiver or decoder provided.  Cannot process xml socket events");
            getLogger().error(
                "Exception constructing XML Socket Receiver", listenerException);
        }

        try {
            is = socket.getInputStream();
        } catch (Exception e) {
            is = null;
            listenerException = e;
            getLogger().error("Exception opening InputStream to " + socket, e);
        }

        if (is != null) {
            String hostName = socket.getInetAddress().getHostName();
            String remoteInfo = hostName + ":" + socket.getPort();

            try {
                //read data from the socket
                //it's up to the individual decoder to handle incomplete event data
                while (true) {
                    byte[] b = new byte[1024];
                    int length = is.read(b);
                    if (length == -1) {
                        getLogger().info(
                            "no bytes read from stream - closing connection.");
                        break;
                    }
                    List<LoggingEvent> v = decoder.decodeEvents(new String(b, 0, length));

                    if (v != null) {

                        for (Object aV : v) {
                            LoggingEvent e = (LoggingEvent) aV;
                            e.setProperty(Constants.HOSTNAME_KEY, hostName);

                            // store the known remote info in an event property
                            e.setProperty("log4j.remoteSourceInfo", remoteInfo);

                            // if configured with a receiver, tell it to post the event
                            if (receiver != null) {
                                receiver.doPost(e);

                                // else post it via the hierarchy
                            } else {
                                // get a logger from the hierarchy. The name of the logger
                                // is taken to be the name contained in the event.
                                remoteLogger = repository.getLogger(e.getLoggerName());

                                //event.logger = remoteLogger;
                                // apply the logger-level filter
                                if (
                                    e.getLevel().isGreaterOrEqual(
                                        remoteLogger.getEffectiveLevel())) {
                                    // finally log the event as if was generated locally
                                    remoteLogger.callAppenders(e);
                                }
                            }
                        }
                    }
                }
            } catch (java.io.EOFException e) {
                getLogger().info("Caught java.io.EOFException closing connection.");
                listenerException = e;
            } catch (java.net.SocketException e) {
                getLogger().info(
                    "Caught java.net.SocketException closing connection.");
                listenerException = e;
            } catch (IOException e) {
                getLogger().info("Caught java.io.IOException: " + e);
                getLogger().info("Closing connection.");
                listenerException = e;
            } catch (Exception e) {
                getLogger().error("Unexpected exception. Closing connection.", e);
                listenerException = e;
            }
        }

        // close the socket
        try {
            if (is != null) {
                is.close();
            }
        } catch (Exception e) {
            //logger.info("Could not close connection.", e);
        }

        // send event to listener, if configured
        if (listener != null) {
            listener.socketClosedEvent(listenerException);
        }
    }
}
