/* Jdwp.java -- Virtual machine to JDWP back-end programming interface
   Copyright (C) 2005, 2006 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.classpath.jdwp;

import gnu.classpath.jdwp.event.Event;
import gnu.classpath.jdwp.event.EventManager;
import gnu.classpath.jdwp.event.EventRequest;
import gnu.classpath.jdwp.exception.JdwpException;
import gnu.classpath.jdwp.processor.PacketProcessor;
import gnu.classpath.jdwp.transport.ITransport;
import gnu.classpath.jdwp.transport.JdwpConnection;
import gnu.classpath.jdwp.transport.TransportException;
import gnu.classpath.jdwp.transport.TransportFactory;

import java.io.IOException;
import java.security.AccessController;
import java.util.HashMap;

/**
 * Main interface from the virtual machine to the JDWP back-end.
 *
 * The thread created by this class is only used for initialization.
 * Once it exits, the JDWP backend is fully initialized.
 *
 * @author Keith Seitz (keiths@redhat.com)
 */
public class Jdwp
  extends Thread
{
  // The single instance of the back-end
  private static Jdwp _instance = null;

  /**
   * Are we debugging? Only true if debugging
   * *and* initialized.
   */
  public static boolean isDebugging = false;

  // Packet processor
  private PacketProcessor _packetProcessor;
  private Thread _ppThread;

  // JDWP configuration properties
  private HashMap _properties;

  // The suspend property of the configure string
  // (-Xrunjdwp:..suspend=<boolean>)
  private static final String _PROPERTY_SUSPEND = "suspend";

  // Connection to debugger
  private JdwpConnection _connection;

  // Are we shutting down the current session?
  private boolean _shutdown;

  // A thread group for the JDWP threads
  private ThreadGroup _group;

  // Initialization synchronization
  private Object _initLock = new Object ();
  private int _initCount = 0;

  /**
   * constructor
   */
  public Jdwp ()
  {
    _shutdown = false;
    _instance = this;
  }

  /**
   * Returns the JDWP back-end, creating an instance of it
   * if one does not already exist.
   */
  public static Jdwp getDefault ()
  {
    return _instance;
  }

  /**
   * Get the thread group used by JDWP threads
   * 
   * @return the thread group
   */
  public ThreadGroup getJdwpThreadGroup()
  {
    return _group;
  }
  
  /**
   * Should the virtual machine suspend on startup?
   */
  public static boolean suspendOnStartup ()
  {
    Jdwp jdwp = getDefault ();
    if (jdwp != null)
      {
	String suspend = (String) jdwp._properties.get (_PROPERTY_SUSPEND);
	if (suspend != null && suspend.equals ("y"))
	  return true;
      }

    return false;
  }

  /**
   * Configures the back-end
   *
   * @param configArgs  a string of configury options
   */
  public void configure (String configArgs)
  {
    _processConfigury (configArgs);
  }

  // A helper function to initialize the transport layer
  private void _doInitialization ()
    throws TransportException
  {
    _group = new ThreadGroup ("JDWP threads");
    // initialize transport
    ITransport transport = TransportFactory.newInstance (_properties);
    _connection = new JdwpConnection (_group, transport);
    _connection.initialize ();
    _connection.start ();

    // Create processor
    _packetProcessor = new PacketProcessor (_connection);
    _ppThread = new Thread (_group, new Runnable ()
      {
	public void run ()
	{
	  AccessController.doPrivileged (_packetProcessor);
	}
      }, "packet processor");
    _ppThread.start ();
  }

  /**
   * Shutdown the JDWP back-end
   *
   * NOTE: This does not quite work properly. See notes in 
   * run() on this subject (catch of InterruptedException).
   */
  public void shutdown ()
  {
    if (!_shutdown)
      {
	_packetProcessor.shutdown ();
	_ppThread.interrupt ();
	_connection.shutdown ();
	_shutdown = true;
	isDebugging = false;

	/* FIXME: probably need to check state of user's
	   program -- if it is suspended, we need to either
	   resume or kill them. */

	interrupt ();
      }
  }

  /**
   * Notify the debugger of an event. This method should not
   * be called if debugging is not active (but it would not
   * cause any harm). Places where event notifications occur
   * should check isDebugging before doing anything.
   *
   * The event is filtered through the event manager before being
   * sent.
   *
   * FIXME: Probably need logic to send multiple events
   * @param event the event to report
   */
  public static void notify (Event event)
  {
    Jdwp jdwp = getDefault ();
    if (jdwp != null)
      {
	EventManager em = EventManager.getDefault ();
	EventRequest request = em.getEventRequest (event);
	if (request != null)
	  {
	    try
	      {
		System.out.println ("Jdwp.notify: sending event " + event);
		sendEvent (request, event);
		jdwp._enforceSuspendPolicy (request.getSuspendPolicy ());
	      }
	    catch (Exception e)
	      {
		/* Really not much we can do. For now, just print out
		   a warning to the user. */
		System.out.println ("Jdwp.notify: caught exception: " + e);
	      }
	  }
      }
  }
  
  /**
   * Sends the event to the debugger.
   *
   * This method bypasses the event manager's filtering.
   *
   * @param  request  the debugger request for the event
   * @param  event    the event to send
   * @throws IOException if a communications failure occurs
   */
  public static void sendEvent (EventRequest request, Event event)
      throws IOException
  {
    Jdwp jdwp = getDefault ();
    if (jdwp != null)
      {
	// !! May need to implement send queue?
	synchronized (jdwp._connection)
	  {
	    jdwp._connection.sendEvent (request, event);
	  }
      }
  }

  // Helper function to enforce suspend policies on event notification
  private void _enforceSuspendPolicy (byte suspendPolicy)
    throws JdwpException
  {
    switch (suspendPolicy)
      {
      case EventRequest.SUSPEND_NONE:
	// do nothing
	break;

      case EventRequest.SUSPEND_THREAD:
	VMVirtualMachine.suspendThread (Thread.currentThread ());
	break;

      case EventRequest.SUSPEND_ALL:
	VMVirtualMachine.suspendAllThreads ();
	break;
      }
  }

  /**
   * Allows subcomponents to specify that they are
   * initialized.
   *
   * Subcomponents include JdwpConnection and PacketProcessor.
   */
  public void subcomponentInitialized ()
  {
    synchronized (_initLock)
      {
	++_initCount;
	_initLock.notify ();
      }
  }

  public void run ()
  {
    try
      {
	_doInitialization ();

	/* We need a little internal synchronization here, so that
	   when this thread dies, the back-end will be fully initialized,
	   ready to start servicing the VM and debugger. */
	synchronized (_initLock)
	  {
	    while (_initCount != 2)
	      _initLock.wait ();
	  }
	_initLock = null;
      }
    catch (Throwable t)
      {
	System.out.println ("Exception in JDWP back-end: " + t);
	System.exit (1);
      }

    /* Force creation of the EventManager. If the event manager
       has not been created when isDebugging is set, it is possible
       that the VM will call Jdwp.notify (which uses EventManager)
       while the EventManager is being created (or at least this is
       a problem with gcj/gij). */
    EventManager.getDefault();

    // Now we are finally ready and initialized
    isDebugging = true;
  }

  // A helper function to process the configure string "-Xrunjdwp:..."
  private void _processConfigury (String configString)
  {
    // Loop through configuration arguments looking for a
    // transport name
    _properties = new HashMap ();
    String[] options = configString.split (",");
    for (int i = 0; i < options.length; ++i)
      {
	String[] property = options[i].split ("=");
	if (property.length == 2)
	  _properties.put (property[0], property[1]);
	// ignore malformed options
      }
  }
}
