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

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>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 ObjectInputStream 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);
    }
  }
}
