/*
 * 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.xml;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;

import org.apache.log4j.helpers.Constants;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.Decoder;
import org.apache.log4j.spi.LoggingEvent;

/**
 * LogFileXMLReceiver will read an xml-formated log file and make the events in the log file
 * available to the log4j framework.
 * <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>
 * Tailing -may- work, but not in all cases (try using a file:// URL). If a process has a log file
 * open, the receiver may be able to read and tail the file. If the process closes the file and
 * reopens the file, the receiver may not be able to continue tailing the file.
 * <p>
 * An expressionFilter may be specified. Only events passing the expression will be forwarded to the
 * log4j framework.
 * <p>
 * Once the event has been "posted", it will be handled by the appenders currently configured in the
 * LoggerRespository.
 * 
 * @author Scott Deboy <sdeboy@apache.org>
 * @since 1.3
 */

public class LogFileXMLReceiver extends Receiver {
    private String fileURL;
    private Rule expressionRule;
    private String filterExpression;
    private String decoder = "org.apache.log4j.xml.XMLDecoder";
    private boolean tailing = false;

    private Decoder decoderInstance;
    private Reader reader;
    private static final String FILE_KEY = "file";
    private String host;
    private String path;
    private boolean useCurrentThread;

    /**
     * Accessor
     * 
     * @return file URL
     */
    public String getFileURL() {
        return fileURL;
    }

    /**
     * Specify the URL of the XML-formatted file to process.
     * 
     * @param fileURL
     */
    public void setFileURL(String fileURL) {
        this.fileURL = fileURL;
    }

    /**
     * Accessor
     * 
     * @return
     */
    public String getDecoder() {
        return decoder;
    }

    /**
     * Specify the class name implementing org.apache.log4j.spi.Decoder that can process the file.
     * 
     * @param _decoder
     */
    public void setDecoder(String _decoder) {
        decoder = _decoder;
    }

    /**
     * Accessor
     * 
     * @return filter expression
     */
    public String getFilterExpression() {
        return filterExpression;
    }

    /**
     * Accessor
     * 
     * @return tailing flag
     */
    public boolean isTailing() {
        return tailing;
    }

    /**
     * Set the 'tailing' flag - may only work on file:// URLs and may stop tailing if the writing
     * process closes the file and reopens.
     * 
     * @param tailing
     */
    public void setTailing(boolean tailing) {
        this.tailing = tailing;
    }

    /**
     * Set the filter expression that will cause only events which pass the filter to be forwarded
     * to the log4j framework.
     * 
     * @param filterExpression
     */
    public void setFilterExpression(String filterExpression) {
        this.filterExpression = filterExpression;
    }

    private boolean passesExpression(LoggingEvent event) {
        if (event != null) {
            if (expressionRule != null) {
                return (expressionRule.evaluate(event, null));
            }
        }
        return true;
    }

    public static void main(String[] args) {
        /*
         * LogFileXMLReceiver test = new LogFileXMLReceiver();
         * test.setFileURL("file:///c:/samplelog.xml"); test.setFilterExpression("level >= TRACE");
         * test.activateOptions();
         */
    }

    /**
     * Close the receiver, release any resources that are accessing the file.
     */
    public void shutdown() {
        try {
            if (reader != null) {
                reader.close();
                reader = null;
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * Process the file
     */
    public void activateOptions() {
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    URL url = new URL(fileURL);
                    host = url.getHost();
                    if (host != null && host.equals("")) {
                        host = FILE_KEY;
                    }
                    path = url.getPath();
                } catch (MalformedURLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                try {
                    if (filterExpression != null) {
                        expressionRule = ExpressionRule.getRule(filterExpression);
                    }
                } catch (Exception e) {
                    getLogger().warn("Invalid filter expression: " + filterExpression, e);
                }

                Class c;
                try {
                    c = Class.forName(decoder);
                    Object o = c.newInstance();
                    if (o instanceof Decoder) {
                        decoderInstance = (Decoder) o;
                    }
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                try {
                    reader = new InputStreamReader(new URL(getFileURL()).openStream());
                    process(reader);
                } catch (FileNotFoundException fnfe) {
                    getLogger().info("file not available");
                } catch (IOException ioe) {
                    getLogger().warn("unable to load file", ioe);
                    return;
                }
            }
        };
        if (useCurrentThread) {
            runnable.run();
        } else {
            Thread thread = new Thread(runnable, "LogFileXMLReceiver-" + getName());

            thread.start();

        }
    }

    private void process(Reader unbufferedReader) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(unbufferedReader);
        char[] content = new char[10000];
        getLogger().debug("processing starting: " + fileURL);
        int length = 0;
        do {
            System.out.println("in do loop-about to process");
            while ((length = bufferedReader.read(content)) > -1) {
                processEvents(decoderInstance.decodeEvents(String.valueOf(content, 0, length)));
            }
            if (tailing) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } while (tailing);
        getLogger().debug("processing complete: " + fileURL);

        shutdown();
    }

    private void processEvents(Collection c) {
        if (c == null) {
            return;
        }

        for (Iterator iter = c.iterator(); iter.hasNext();) {
            LoggingEvent evt = (LoggingEvent) iter.next();
            if (passesExpression(evt)) {
                if (evt.getProperty(Constants.HOSTNAME_KEY) != null) {
                    evt.setProperty(Constants.HOSTNAME_KEY, host);
                }
                if (evt.getProperty(Constants.APPLICATION_KEY) != null) {
                    evt.setProperty(Constants.APPLICATION_KEY, path);
                }
                doPost(evt);
            }
        }
    }

    /**
     * When true, this property uses the current Thread to perform the import, otherwise when false
     * (the default), a new Thread is created and started to manage the import.
     * 
     * @return
     */
    public final boolean isUseCurrentThread() {
        return useCurrentThread;
    }

    /**
     * Sets whether the current Thread or a new Thread is created to perform the import, the default
     * being false (new Thread created).
     * 
     * @param useCurrentThread
     */
    public final void setUseCurrentThread(boolean useCurrentThread) {
        this.useCurrentThread = useCurrentThread;
    }

}