/* VirtualMachineCommandSet.java -- class to implement the VirtualMachine
   Command Set
   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
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.processor;

import gnu.classpath.jdwp.JdwpConstants;
import gnu.classpath.jdwp.VMFrame;
import gnu.classpath.jdwp.VMVirtualMachine;
import gnu.classpath.jdwp.exception.JdwpException;
import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
import gnu.classpath.jdwp.exception.NotImplementedException;
import gnu.classpath.jdwp.id.ObjectId;
import gnu.classpath.jdwp.id.ReferenceTypeId;
import gnu.classpath.jdwp.util.JdwpString;
import gnu.classpath.jdwp.util.Signature;

import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;

/**
 * A class representing the VirtualMachine Command Set.
 * 
 * @author Aaron Luchko <aluchko@redhat.com>
 */
public class VirtualMachineCommandSet
  extends CommandSet
{
  public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command)
    throws JdwpException
  {
    boolean shutdown = false;
    try
      {
        switch (command)
          {
          case JdwpConstants.CommandSet.VirtualMachine.VERSION:
            executeVersion(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.CLASSES_BY_SIGNATURE:
            executeClassesBySignature(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.ALL_CLASSES:
            executeAllClasses(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.ALL_THREADS:
            executeAllThreads(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.TOP_LEVEL_THREAD_GROUPS:
            executeTopLevelThreadGroups(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.IDSIZES:
            executeIDsizes(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.DISPOSE:
            shutdown = true;
            executeDispose(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.SUSPEND:
            executeSuspend(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.RESUME:
            executeResume(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.EXIT:
	    shutdown = true;
            executeExit(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.CREATE_STRING:
            executeCreateString(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.CAPABILITIES:
            executeCapabilities(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.CLASS_PATHS:
            executeClassPaths(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.DISPOSE_OBJECTS:
            executeDisposeObjects(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.HOLD_EVENTS:
            executeHoldEvents(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.RELEASE_EVENTS:
            executeReleaseEvents(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.CAPABILITIES_NEW:
            executeCapabilitiesNew(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.REDEFINE_CLASSES:
            executeRedefineClasses(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.SET_DEFAULT_STRATUM:
            executeSetDefaultStratum(bb, os);
            break;
          case JdwpConstants.CommandSet.VirtualMachine.ALL_CLASSES_WITH_GENERIC:
            executeAllClassesWithGeneric(bb, os);
            break;
          default:
            throw new NotImplementedException("Command " + command +
            " not found in VirtualMachine Command Set.");
          }
      }
    catch (IOException ex)
      {
        // The DataOutputStream we're using isn't talking to a socket at all
        // So if we throw an IOException we're in serious trouble
        throw new JdwpInternalErrorException(ex);
      }

    return shutdown;
  }

  private void executeVersion(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {

    Properties props = System.getProperties();

    int jdwpMajor = JdwpConstants.Version.MAJOR;
    int jdwpMinor = JdwpConstants.Version.MINOR;
    // The description field is pretty loosely defined
    String description = "JDWP version " + jdwpMajor + "." + jdwpMinor
                         + ", JVM version " + props.getProperty("java.vm.name")
                         + " " + props.getProperty("java.vm.version") + " "
                         + props.getProperty("java.version");
    String vmVersion = props.getProperty("java.version");
    String vmName = props.getProperty("java.vm.name");
    JdwpString.writeString(os, description);
    os.writeInt(jdwpMajor);
    os.writeInt(jdwpMinor);
    JdwpString.writeString(os, vmName);
    JdwpString.writeString(os, vmVersion);
  }

  private void executeClassesBySignature(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    String sig = JdwpString.readString(bb);
    ArrayList allMatchingClasses = new ArrayList();

    // This will be an Iterator over all loaded Classes
    Iterator iter = VMVirtualMachine.getAllLoadedClasses();

    while (iter.hasNext())
      {
        Class clazz = (Class) iter.next();
        String clazzSig = Signature.computeClassSignature(clazz);
        if (clazzSig.equals(sig))
          allMatchingClasses.add(clazz);
      }

    os.writeInt(allMatchingClasses.size());
    for (int i = 0; i < allMatchingClasses.size(); i++)
      {
        Class clazz = (Class) allMatchingClasses.get(i);
        ReferenceTypeId id = idMan.getReferenceTypeId(clazz);
        id.writeTagged(os);
        int status = VMVirtualMachine.getClassStatus(clazz);
        os.writeInt(status);
      }
  }

  private void executeAllClasses(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    // Disable garbage collection while we're collecting the info on loaded
    // classes so we some classes don't get collected between the time we get
    // the count and the time we get the list
    //VMVirtualMachine.disableGarbageCollection();

    int classCount = VMVirtualMachine.getAllLoadedClassesCount();
    os.writeInt(classCount);

    // This will be an Iterator over all loaded Classes
    Iterator iter = VMVirtualMachine.getAllLoadedClasses();
    //VMVirtualMachine.enableGarbageCollection();
    int count = 0;

    // Note it's possible classes were created since out classCount so make
    // sure we don't write more classes than we told the debugger
    while (iter.hasNext() && count++ < classCount)
      {
        Class clazz = (Class) iter.next();
        ReferenceTypeId id = idMan.getReferenceTypeId(clazz);
        id.writeTagged(os);
        String sig = Signature.computeClassSignature(clazz);
        JdwpString.writeString(os, sig);
        int status = VMVirtualMachine.getClassStatus(clazz);
        os.writeInt(status);
      }
  }

  private void executeAllThreads(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup();
    ThreadGroup root = getRootThreadGroup(jdwpGroup);

    int numThreads = root.activeCount();
    Thread allThreads[] = new Thread[numThreads];
    root.enumerate(allThreads);

    // We need to loop through for the true count since some threads may have
    // been destroyed since we got
    // activeCount so those spots in the array will be null. As well we must
    // ignore any threads that belong to jdwp
    numThreads = 0;
    for (int i = 0; i < allThreads.length; i++)
      {
        Thread thread = allThreads[i];
        if (thread == null)
          break; // No threads after this point
        if (!thread.getThreadGroup().equals(jdwpGroup))
          numThreads++;
      }

    os.writeInt(numThreads);

    for (int i = 0; i < allThreads.length; i++)
      {
        Thread thread = allThreads[i];
        if (thread == null)
          break; // No threads after this point
        if (!thread.getThreadGroup().equals(jdwpGroup))
          idMan.getObjectId(thread).write(os);
      }
  }

  private void executeTopLevelThreadGroups(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup ();
    ThreadGroup root = getRootThreadGroup(jdwpGroup);

    os.writeInt(1); // Just one top level group allowed?
    idMan.getObjectId(root);
  }

  private void executeDispose(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // resumeAllThreads isn't sufficient as a thread may have been
    // suspended multiple times, we likely need a way to keep track of how many
    // times a thread has been suspended or else a stronger resume method for
    // this purpose
    // VMVirtualMachine.resumeAllThreads ();

    // Simply shutting down the jdwp layer will take care of the rest of the
    // shutdown other than disabling debugging in the VM
    // VMVirtualMachine.disableDebugging();

    // Don't implement this until we're sure how to remove all the debugging
    // effects from the VM.
    throw new NotImplementedException(
      "Command VirtualMachine.Dispose not implemented");

  }

  private void executeIDsizes(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    os.writeInt(ObjectId.SIZE); // fieldId FIXME
    os.writeInt(ObjectId.SIZE); // methodId FIXME
    os.writeInt(ObjectId.SIZE); // objectId
    os.writeInt(ReferenceTypeId.SIZE); // referenceTypeId
    os.writeInt(VMFrame.SIZE); // frameId
  }

  private void executeSuspend(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    VMVirtualMachine.suspendAllThreads ();
  }

  private void executeResume(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    VMVirtualMachine.resumeAllThreads ();
  }

  private void executeExit(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    int exitCode = bb.getInt();
    System.exit (exitCode);
  }

  private void executeCreateString(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    String string = JdwpString.readString(bb);
    ObjectId stringId = idMan.getObjectId(string);
    
    // Since this string isn't referenced anywhere we'll disable garbage
    // collection on it so it's still around when the debugger gets back to it.
    stringId.disableCollection();
    stringId.write(os);
  }

  private void executeCapabilities(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    // Store these somewhere?
    os.writeBoolean(false); // canWatchFieldModification
    os.writeBoolean(false); // canWatchFieldAccess
    os.writeBoolean(false); // canGetBytecodes
    os.writeBoolean(false); // canGetSyntheticAttribute
    os.writeBoolean(false); // canGetOwnedMonitorInfo
    os.writeBoolean(false); // canGetCurrentContendedMonitor
    os.writeBoolean(false); // canGetMonitorInfo
  }

  private void executeClassPaths(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    String baseDir = System.getProperty("user.dir");
    JdwpString.writeString(os, baseDir);

    // Find and write the classpath
    String classPath = System.getProperty("java.class.path");
    String[] paths = classPath.split(":");

    os.writeInt(paths.length);
    for (int i = 0; i < paths.length; i++)
      JdwpString.writeString(os, paths[i]);

    // Now the bootpath
    String bootPath = System.getProperty("sun.boot.class.path");
    paths = bootPath.split(":");
    os.writeInt(paths.length);
    for (int i = 0; i < paths.length; i++)
      JdwpString.writeString(os, paths[i]);
  }

  private void executeDisposeObjects(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // Instead of going through the list of objects they give us it's probably
    // better just to find the garbage collected objects ourselves
    //idMan.update();
  }

  private void executeHoldEvents(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // Going to have to implement a send queue somewhere and do this without
    // triggering events
    // Until then just don't implement
    throw new NotImplementedException(
      "Command VirtualMachine.HoldEvents not implemented");
  }

  // Opposite of executeHoldEvents
  private void executeReleaseEvents(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    throw new NotImplementedException(
      "Command VirtualMachine.ReleaseEvents not implemented");
  }

  private void executeCapabilitiesNew(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    // Store these somewhere?
    final int CAPABILITIES_NEW_SIZE = 32;
    os.writeBoolean(false); // canWatchFieldModification
    os.writeBoolean(false); // canWatchFieldAccess
    os.writeBoolean(false); // canGetBytecodes
    os.writeBoolean(false); // canGetSyntheticAttribute
    os.writeBoolean(false); // canGetOwnedMonitorInfo
    os.writeBoolean(false); // canGetCurrentContendedMonitor
    os.writeBoolean(false); // canGetMonitorInfo
    os.writeBoolean(false); // canRedefineClasses
    os.writeBoolean(false); // canAddMethod
    os.writeBoolean(false); // canUnrestrictedlyRedefineClasses
    os.writeBoolean(false); // canPopFrames
    os.writeBoolean(false); // canUseInstanceFilters
    os.writeBoolean(false); // canGetSourceDebugExtension
    os.writeBoolean(false); // canRequestVMDeathEvent
    os.writeBoolean(false); // canSetDefaultStratum
    for (int i = 15; i < CAPABILITIES_NEW_SIZE; i++)
      // Future capabilities
      // currently unused
      os.writeBoolean(false); // Set to false
  }

  private void executeRedefineClasses(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // Optional command, don't implement
    throw new NotImplementedException(
      "Command VirtualMachine.RedefineClasses not implemented");
  }

  private void executeSetDefaultStratum(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // Optional command, don't implement
    throw new NotImplementedException(
      "Command VirtualMachine.SetDefaultStratum not implemented");
  }

  private void executeAllClassesWithGeneric(ByteBuffer bb, DataOutputStream os)
    throws JdwpException
  {
    // We don't handle generics
    throw new NotImplementedException(
      "Command VirtualMachine.AllClassesWithGeneric not implemented");
  }

  /**
   * Find the root ThreadGroup of this ThreadGroup
   */
  private ThreadGroup getRootThreadGroup(ThreadGroup group)
  {
    ThreadGroup parent = group.getParent();

    while (parent != null)
      {
        group = parent;
        parent = group.getParent();
      }
    return group; // This group was the root
  }
}
