/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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.chainsaw.vfs;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.RandomAccessContent;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.provider.URLFileName;
import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;
import org.apache.commons.vfs.util.RandomAccessMode;
import org.apache.log4j.chainsaw.receivers.VisualReceiver;
import org.apache.log4j.varia.LogFilePatternReceiver;

/**
 * A VFS-enabled version of org.apache.log4j.varia.LogFilePatternReceiver.
 * 
 * VFSLogFilePatternReceiver can parse and tail log files, converting entries into
 * LoggingEvents.  If the file doesn't exist when the receiver is initialized, the
 * receiver will look for the file once every 10 seconds.
 * <p>
 * See the Chainsaw page (http://logging.apache.org/log4j/docs/chainsaw.html) for information
 * on how to set up Chainsaw with VFS.
 * <p>
 * See http://jakarta.apache.org/commons/vfs/filesystems.html for a list of VFS-supported
 * file systems and the URIs needed to access the file systems.
 * <p>
 * Because some VFS file systems allow you to provide username/password, this receiver
 * provides an optional GUI dialog for entering the username/password fields instead 
 * of requiring you to hard code usernames and passwords into the URI.
 * <p>
 * If the 'promptForUserInfo' param is set to true (default is false), 
 * the receiver will wait for a call to 'setContainer', and then display 
 * a username/password dialog.
 * <p>
 * If you are using this receiver without a GUI, don't set promptForUserInfo 
 * to true - it will block indefinitely waiting for a visual component.
 * <p> 
 * If the 'promptForUserInfo' param is set to true, the fileURL should -leave out- 
 * the username/password portion of the VFS-supported URI.  Examples:
 * <p>
 * An sftp URI that would be used with promptForUserInfo=true:
 * sftp://192.168.1.100:22/home/thisuser/logfile.txt
 * <p>
 * An sftp URI that would be used with promptForUserInfo=false:
 * sftp://username:password@192.168.1.100:22/home/thisuser/logfile.txt
 * <p>
 * This receiver relies on java.util.regex features to perform the parsing of text in the 
 * log file, however the only regular expression field explicitly supported is 
 * a glob-style wildcard used to ignore fields in the log file if needed.  All other
 * fields are parsed by using the supplied keywords.
 * <p>
 * <b>Features:</b><br>
 * - specify the URL of the log file to be processed<br>
 * - specify the timestamp format in the file (if one exists, using patterns from {@link java.text.SimpleDateFormat})<br>
 * - specify the pattern (logFormat) used in the log file using keywords, a wildcard character (*) and fixed text<br>
 * - 'tail' the file (allows the contents of the file to be continually read and new events processed)<br>
 * - supports the parsing of multi-line messages and exceptions
 * - to access 
 *<p>
 * <b>Keywords:</b><br>
 * TIMESTAMP<br>
 * LOGGER<br>
 * LEVEL<br>
 * THREAD<br>
 * CLASS<br>
 * FILE<br>
 * LINE<br>
 * METHOD<br>
 * RELATIVETIME<br>
 * MESSAGE<br>
 * NDC<br>
 * PROP(key)<br>
 * <p>
 * Use a * to ignore portions of the log format that should be ignored
 * <p>
 * Example:<br>
 * If your file's patternlayout is this:<br>
 * <b>%d %-5p [%t] %C{2} (%F:%L) - %m%n</b>
 *<p>
 * specify this as the log format:<br>
 * <b>TIMESTAMP LEVEL [THREAD] CLASS (FILE:LINE) - MESSAGE</b>
 *<p>
 * To define a PROPERTY field, use PROP(key)
 * <p>
 * Example:<br> 
 * If you used the RELATIVETIME pattern layout character in the file, 
 * you can use PROP(RELATIVETIME) in the logFormat definition to assign 
 * the RELATIVETIME field as a property on the event.
 * <p>
 * If your file's patternlayout is this:<br>
 * <b>%r [%t] %-5p %c %x - %m%n</b>
 *<p>
 * specify this as the log format:<br>
 * <b>PROP(RELATIVETIME) [THREAD] LEVEL LOGGER * - MESSAGE</b>
 * <p>
 * Note the * - it can be used to ignore a single word or sequence of words in the log file
 * (in order for the wildcard to ignore a sequence of words, the text being ignored must be
 *  followed by some delimiter, like '-' or '[') - ndc is being ignored in this example.
 * <p>
 * Assign a filterExpression in order to only process events which match a filter.
 * If a filterExpression is not assigned, all events are processed.
 *<p>
 * <b>Limitations:</b><br>
 * - no support for the single-line version of throwable supported by patternlayout<br>
 *   (this version of throwable will be included as the last line of the message)<br>
 * - the relativetime patternLayout character must be set as a property: PROP(RELATIVETIME)<br>
 * - messages should appear as the last field of the logFormat because the variability in message content<br>
 * - exceptions are converted if the exception stack trace (other than the first line of the exception)<br>
 *   is stored in the log file with a tab followed by the word 'at' as the first characters in the line<br>
 * - tailing may fail if the file rolls over. 
 *<p>
 * <b>Example receiver configuration settings</b> (add these as params, specifying a LogFilePatternReceiver 'plugin'):<br>
 * param: "timestampFormat" value="yyyy-MM-d HH:mm:ss,SSS"<br>
 * param: "logFormat" value="RELATIVETIME [THREAD] LEVEL LOGGER * - MESSAGE"<br>
 * param: "fileURL" value="file:///c:/events.log"<br>
 * param: "tailing" value="true"
 * param: "promptForUserInfo" value="false"
 *<p>
 * This configuration will be able to process these sample events:<br>
 * 710    [       Thread-0] DEBUG                   first.logger first - <test>   <test2>something here</test2>   <test3 blah=something/>   <test4>       <test5>something else</test5>   </test4></test><br>
 * 880    [       Thread-2] DEBUG                   first.logger third - <test>   <test2>something here</test2>   <test3 blah=something/>   <test4>       <test5>something else</test5>   </test4></test><br>
 * 880    [       Thread-0] INFO                    first.logger first - infomsg-0<br>
 * java.lang.Exception: someexception-first<br>
 *     at Generator2.run(Generator2.java:102)<br>
 *
 *@author Scott Deboy
 */
public class VFSLogFilePatternReceiver extends LogFilePatternReceiver implements VisualReceiver {

  private boolean promptForUserInfo = false;
  private Container container;
  private Object waitForContainerLock = new Object();
  private boolean autoReconnect;
  private VFSReader vfsReader;

    public VFSLogFilePatternReceiver() {
    super();
  }

  public void shutdown() {
    getLogger().info("shutdown VFSLogFilePatternReceiver");
    active = false;
	container = null;
    if (vfsReader != null) {
      vfsReader.terminate();
      vfsReader = null;
    }
  }
  
  /**
   * If set to true, will cause the receiver to block indefinitely until 'setContainer' has been called, 
   * at which point a username/password dialog will appear.
   * 
   * @param promptForUserInfo
   */
  public void setPromptForUserInfo(boolean promptForUserInfo) {
	  this.promptForUserInfo = promptForUserInfo;
  }
  
  public boolean isPromptForUserInfo() {
	  return promptForUserInfo;
  }

    /**
     * Accessor
     * @return
     */
    public boolean isAutoReconnect() {
      return autoReconnect;
    }

    /**
     * Mutator
     * @param autoReconnect
     */
    public void setAutoReconnect(boolean autoReconnect) {
        this.autoReconnect = autoReconnect;
    }

  /**
   * Implementation of VisualReceiver interface - allows this receiver to provide
   * a username/password dialog.
   */
  public void setContainer(Container container) {
      if (promptForUserInfo) {
    	  synchronized(waitForContainerLock) {
    		  this.container=container;
    		  waitForContainerLock.notify();
    	  }
      }
  }

  /**
   * Read and process the log file.
   */
  public void activateOptions() {
      //we don't want to call super.activateOptions, but we do want active to be set to true
      active = true;
      //on receiver restart, only prompt for credentials if we don't already have them
      if (promptForUserInfo && getFileURL().indexOf("@") == -1) {
    	  /*
    	  if promptforuserinfo is true, wait for a reference to the container
    	  (via the VisualReceiver callback).

    	  We need to display a login dialog on top of the container, so we must then
    	  wait until the container has been added to a frame
    	  */

    	  //get a reference to the container
    	  new Thread(new Runnable() {
    		  public void run() {
    	  synchronized(waitForContainerLock) {
    		  while (container == null) {
    			  try {
    				  waitForContainerLock.wait(1000);
    				  getLogger().debug("waiting for setContainer call");
    			  } catch (InterruptedException ie){}
    		  }
    	  }

    	  Frame containerFrame1;
          if (container instanceof Frame) {
              containerFrame1 = (Frame)container;
          } else {
              synchronized(waitForContainerLock) {
                  //loop until the container has a frame
                  while ((containerFrame1 = (Frame)SwingUtilities.getAncestorOfClass(Frame.class, container)) == null) {
                      try {
                          waitForContainerLock.wait(1000);
                          getLogger().debug("waiting for container's frame to be available");
                      } catch (InterruptedException ie) {}
                  }
              }
          }
            final Frame containerFrame = containerFrame1;
    	  	  //create the dialog
    	  	  SwingUtilities.invokeLater(new Runnable() {
    	  		public void run() {
    	  			  Frame owner = null;
    	  			  if (container != null) {
    	  				  owner = (Frame)SwingUtilities.getAncestorOfClass(Frame.class, containerFrame);
    	  			  }
    	  			  final UserNamePasswordDialog f = new UserNamePasswordDialog(owner);
    	  			  f.pack();
    	  			  Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    	  			  f.setLocation(d.width /2, d.height/2);
    	  			  f.setVisible(true);
    	  				if (null == f.getUserName() || null == f.getPassword()) {
    	  					getLogger().info("Username and password not both provided, not using credentials");
    	  				} else {
    	  				    String oldURL = getFileURL();
    	  					int index = oldURL.indexOf("://");
    	  					String firstPart = oldURL.substring(0, index);
    	  					String lastPart = oldURL.substring(index + "://".length());
    	  					setFileURL(firstPart + "://" + f.getUserName()+ ":" + new String(f.getPassword()) + "@" + lastPart);

    	  			        setHost(oldURL.substring(0, index + "://".length()));
    	  		            setPath(oldURL.substring(index + "://".length()));
    	  				}
                        vfsReader = new VFSReader();
    	  				new Thread(vfsReader).start();
    	  			  }
    	  		  });
    		  }}).start();
      } else {
        //starts with protocol:/  but not protocol://
        String oldURL = getFileURL();
        if (oldURL != null && oldURL.indexOf(":/") > -1 && oldURL.indexOf("://") == -1) {
          int index = oldURL.indexOf(":/");
          String lastPart = oldURL.substring(index + ":/".length());
          int passEndIndex = lastPart.indexOf("@");
          if (passEndIndex > -1) { //we have a username/password
              setHost(oldURL.substring(0, index + ":/".length()));
              setPath(lastPart.substring(passEndIndex + 1));
          }
          vfsReader = new VFSReader();
          new Thread(vfsReader).start();
        } else if (oldURL != null && oldURL.indexOf("://") > -1) {
        //starts with protocol://
            int index = oldURL.indexOf("://");
            String lastPart = oldURL.substring(index + "://".length());
            int passEndIndex = lastPart.indexOf("@");
            if (passEndIndex > -1) { //we have a username/password
                setHost(oldURL.substring(0, index + "://".length()));
                setPath(lastPart.substring(passEndIndex + 1));
            }
            vfsReader = new VFSReader();
            new Thread(vfsReader).start();
        } else {
            getLogger().info("null URL - unable to parse file");
        }
      }
   }

  private class VFSReader implements Runnable {
      private boolean terminated = false;
      private Reader reader;
      private FileObject fileObject;

      public void run() {
        	//thread should end when we're no longer active
            while (reader == null && !terminated) {
            	int atIndex = getFileURL().indexOf("@");
            	int protocolIndex = getFileURL().indexOf("://");
            	
            	String loggableFileURL = atIndex > -1? getFileURL().substring(0, protocolIndex + "://".length()) + "username:password" + getFileURL().substring(atIndex) : getFileURL();
                getLogger().info("attempting to load file: " + loggableFileURL);
                try {
                    FileSystemManager fileSystemManager = VFS.getManager();
                    FileSystemOptions opts = new FileSystemOptions();
                    //if jsch not in classpath, can get NoClassDefFoundError here
                    try {
                    	SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
                    } catch (NoClassDefFoundError ncdfe) {
                    	getLogger().warn("JSch not on classpath!", ncdfe);
                    }

                    fileObject = fileSystemManager.resolveFile(getFileURL(), opts);
                    if (fileObject.exists()) {
                        reader = new InputStreamReader(fileObject.getContent().getInputStream() , "UTF-8");
                        //now that we have a reader, remove additional portions of the file url (sftp passwords, etc.)
                        //check to see if the name is a URLFileName..if so, set file name to not include username/pass
                        if (fileObject.getName() instanceof URLFileName) {
                            URLFileName urlFileName = (URLFileName) fileObject.getName();
                            setHost(urlFileName.getHostName());
                            setPath(urlFileName.getPath());
                        }
                    } else {
                        getLogger().info(loggableFileURL + " not available - will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis");
                    }
                } catch (FileSystemException fse) {
                    getLogger().info(loggableFileURL + " not available - may be due to incorrect credentials, but will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis", fse);
                } catch (UnsupportedEncodingException e) {
                    getLogger().info("UTF-8 not available", e);
                }
                if (reader == null) {
                    synchronized (this) {
                        try {
                            wait(MISSING_FILE_RETRY_MILLIS);
                        } catch (InterruptedException ie) {}
                    }
                }
            }
            if (terminated) {
                //shut down while waiting for a file
                return;
            }
            initialize();
            getLogger().debug(getPath() + " exists");

            do {
                long lastFilePointer = 0;
                long lastFileSize = 0;
                createPattern();
                try {
                    do {
                        FileSystemManager fileSystemManager = VFS.getManager();
                        FileSystemOptions opts = new FileSystemOptions();
                        //if jsch not in classpath, can get NoClassDefFoundError here
                        try {
                            SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
                        } catch (NoClassDefFoundError ncdfe) {
                            getLogger().warn("JSch not on classpath!", ncdfe);
                        }

                        //fileobject was created above, release it and construct a new one
                        if (fileObject != null) {
                            fileObject.getFileSystem().getFileSystemManager().closeFileSystem(fileObject.getFileSystem());
                            fileObject.close();
                            fileObject = null;
                        }
                        fileObject = fileSystemManager.resolveFile(getFileURL(), opts);

                        //file may not exist..
                        boolean fileLarger = false;
                        if (fileObject != null && fileObject.exists()) {
                            try {
                                //available in vfs as of 30 Mar 2006 - will load but not tail if not available
                                fileObject.refresh();
                            } catch (Error err) {
                                getLogger().info(getPath() + " - unable to refresh fileobject", err);
                            }
                            //could have been truncated or appended to (don't do anything if same size)
                            if (fileObject.getContent().getSize() < lastFileSize) {
                                reader = new InputStreamReader(fileObject.getContent().getInputStream(), "UTF-8");
                                getLogger().debug(getPath() + " was truncated");
                                lastFileSize = 0; //seek to beginning of file
                                lastFilePointer = 0;
                            } else if (fileObject.getContent().getSize() > lastFileSize) {
                                fileLarger = true;
                                RandomAccessContent rac = fileObject.getContent().getRandomAccessContent(RandomAccessMode.READ);
                                rac.seek(lastFilePointer);
                                reader = new InputStreamReader(rac.getInputStream(), "UTF-8");
                                BufferedReader bufferedReader = new BufferedReader(reader);
                                process(bufferedReader);
                                lastFilePointer = rac.getFilePointer();
                                lastFileSize = fileObject.getContent().getSize();
                                rac.close();
                            }
                            try {
                                if (reader != null) {
                                    reader.close();
                                    reader = null;
                                }
                            } catch (IOException ioe) {
                                getLogger().debug(getPath() + " - unable to close reader", ioe);
                            }
                        } else {
                            getLogger().info(getPath() + " - not available - will re-attempt to load after waiting " + getWaitMillis() + " millis");
                        }

                        try {
                            synchronized (this) {
                                wait(getWaitMillis());
                            }
                        } catch (InterruptedException ie) {}
                        if (isTailing() && fileLarger && !terminated) {
                            getLogger().debug(getPath() + " - tailing file - file size: " + lastFileSize);
                        }
                    } while (isTailing() && !terminated);
                } catch (IOException ioe) {
                    getLogger().info(getPath() + " - exception processing file", ioe);
                    try {
                        if (fileObject != null) {
                            fileObject.close();
                        }
                    } catch (FileSystemException e) {
                        getLogger().info(getPath() + " - exception processing file", e);
                    }
                    try {
                        synchronized(this) {
                            wait(getWaitMillis());
                        }
                    } catch (InterruptedException ie) {}
                }
            } while (isAutoReconnect() && !terminated);
            getLogger().debug(getPath() + " - processing complete");
        }

      public void terminate()
      {
          terminated = true;
      }
  }
  
  public class UserNamePasswordDialog extends JDialog {
	  private String userName;
	  private char[] password;
	  private UserNamePasswordDialog(Frame containerFrame) {
		  super(containerFrame, "Login", true);
	      JPanel panel = new JPanel(new GridBagLayout());
	      GridBagConstraints gc = new GridBagConstraints();
	      gc.fill=GridBagConstraints.NONE;

	      gc.anchor=GridBagConstraints.NORTH;
	      gc.gridx=0;
	      gc.gridy=0;
	      gc.gridwidth=3;
	      gc.insets=new Insets(7, 7, 7, 7);
	      panel.add(new JLabel("URI: " + getFileURL()), gc);
	      
	      gc.gridx=0;
	      gc.gridy=1;
	      gc.gridwidth=1;
	      gc.insets=new Insets(2, 2, 2, 2);
	      panel.add(new JLabel("Username"), gc);

		  gc.gridx=1;
		  gc.gridy=1;
		  gc.gridwidth=2;
		  gc.weightx=1.0;
	      gc.fill=GridBagConstraints.HORIZONTAL;

		  final JTextField userNameTextField = new JTextField(15);
		  panel.add(userNameTextField, gc);
		  
		  gc.gridx=0;
		  gc.gridy=2;
		  gc.gridwidth=1;
	      gc.fill=GridBagConstraints.NONE;

		  panel.add(new JLabel("Password"), gc);

		  gc.gridx=1;
		  gc.gridy=2;
		  gc.gridwidth=2;
	      gc.fill=GridBagConstraints.HORIZONTAL;

		  final JPasswordField passwordTextField = new JPasswordField(15);
		  panel.add(passwordTextField, gc);
		  
		  gc.gridy=3;
		  gc.anchor=GridBagConstraints.SOUTH;
	      gc.fill=GridBagConstraints.NONE;

		  JButton submitButton = new JButton(" Submit ");
		  panel.add(submitButton, gc);

		  getContentPane().add(panel);
		  submitButton.addActionListener(new ActionListener(){
			  public void actionPerformed(ActionEvent evt) {
				  userName = userNameTextField.getText();
				  password = passwordTextField.getPassword();
				  getContentPane().setVisible(false);
				  UserNamePasswordDialog.this.dispose();
			  }
		  });
	  }
	 
	  public String getUserName() {
		  return userName;
	  }
	  
	  public char[] getPassword() {
		  return password;
	  }
  }
}
