/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This file is part of SableVM.                             *
 * See the file "LICENSE" for Copyright information and the  *
 * terms and conditions for copying, distribution and        *
 * modification of SableVM.                                  *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

package java.lang;

import java.util.*;
import java.lang.reflect.*;

class StartAppHelper extends Thread
{

  private int suspend;
  private String[] parameters;
  private Class[] parameterTypes;
  private Object[] parameterList;
  private String className;
  private Class mainClass;
  private Method mainMethod;

  public native void proper_suspend ();

  public StartAppHelper (String className, String[] parameters, int suspend)
  {
    this.className = className;
    this.parameters = parameters;
    this.parameterTypes = new Class[1];
    this.parameterList = new Object[1];
    this.parameterList[0] = parameters;
    this.suspend = suspend;
  }

  boolean setup()
  {

    /* get the class whose name has been passed in parameters */
    try
    {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      mainClass = cl.loadClass(this.className);
    }
    catch (Exception e)
    {
      System.out.println ("Error: exception thrown during class access!");
      return false;
    }

    /* get the passed parameters type */
    this.parameterTypes[0] = this.parameters.getClass();

    /* get the main */
    try
    {
      mainMethod = mainClass.getMethod("main", parameterTypes);
    }
    catch (Exception e)
    {
      System.out.println ("Error: exception thrown during method access!");
      return false;
    }
    return true;
  }

  public void run()
  {
    /* suspend the thread before the main method */
    if (this.suspend == 1)
    {
      this.proper_suspend();
    }

    /* call the main method */
    /* as main is static, one can invoke it from the Class
       not from the instance */
    try
    {
      mainMethod.invoke(null, this.parameterList);
    }
    catch (Exception e)
    {
      System.out.println ("Error: exception thrown running method !");
      System.exit (0);
    }
  }
}

class JDWPStart
{
  static StartAppHelper helper;

  /* load the jdwp library */
  static {
    System.loadLibrary ("jdwp");
  }

  public native void load
  (String transport, int server, String address,
   String launch, String onthrow, int onuncaught,
   int stdalloc, int strict, int suspend,
   int port, String start, Thread t, String[] args);

  /* main */
  /* NOTE : all Java creation and initialization must be done
     during debugger initialization to avoid any interaction 
     with the application being debugged */
  public static void main(String[] args)
  {
    JDWPStart jdwpstart = new JDWPStart();
    Thread thread = new Thread ();

    /* options in spec */
    String transport;
    String str_server;
    int server = 0;
    String str_address;
    String address = "localhost";
    String launch;
    String onthrow;
    String str_onuncaught;
    int onuncaught = 0;
    String str_stdalloc;
    int stdalloc = 0;
    String str_strict;
    int strict = 0;
    String str_suspend;
    int suspend = 1;
    String str_port;
    int port = -1;
    /* options */
    String start;
    /* used to parse */
    boolean returnTokens = false;
    String delimProp = "=";
    String delimAdd = ":";
    String token = null;

    str_address = System.getProperty("sablevm.jdwp.address");
    if (str_address != null)
    {
      StringTokenizer addressParser = new StringTokenizer (str_address, delimAdd, returnTokens);
      if (addressParser.countTokens () == 2)
      {
        address = addressParser.nextToken ();
        port = Integer.parseInt(addressParser.nextToken ());
      }
      else if (addressParser.countTokens () == 1)
      {
        port = Integer.parseInt(str_address);
      }
      else
      {
        System.out.println("Error : invalid address value !");
        System.exit (0);
      }
    }

    /* options */

    transport = System.getProperty("sablevm.jdwp.transport");

    str_server = System.getProperty("sablevm.jdwp.server");
    if (str_server != null)
    {
      if (str_server.equalsIgnoreCase("on") || str_server.equalsIgnoreCase("true")
          || str_server.equalsIgnoreCase("y"))
      {
        server = 1;
      }
      else if (str_server.equalsIgnoreCase("off") || str_server.equalsIgnoreCase("false")
               || str_server.equalsIgnoreCase("n"))
      {
        server = 0;
      }
      else
      {
        System.out.println ("Error: invalid option value in server !");
        System.exit (0);
      }
    }


    launch = System.getProperty("sablevm.jdwp.launch");


    onthrow = System.getProperty("sablevm.jdwp.onthrow");

    str_onuncaught = System.getProperty("sablevm.jdwp.onuncaught");
    if (str_onuncaught != null)
    {
      if (str_onuncaught.equalsIgnoreCase("on") || str_onuncaught.equalsIgnoreCase("true")
          || str_onuncaught.equalsIgnoreCase("y"))
      {
        onuncaught = 1;
      }
      else if (str_onuncaught.equalsIgnoreCase("off") || str_onuncaught.equalsIgnoreCase("false")
               || str_onuncaught.equalsIgnoreCase("n"))
      {
        onuncaught = 0;
      }
      else
      {
        System.out.println ("Error: invalid option value in onuncaught !");
        System.exit (0);
      }
    }

    str_stdalloc = System.getProperty("sablevm.jdwp.stdalloc");
    if (str_stdalloc != null)
    {
      if (str_stdalloc.equalsIgnoreCase("on") || str_stdalloc.equalsIgnoreCase("true")
          || str_stdalloc.equalsIgnoreCase("y"))
      {
        stdalloc = 1;
      }
      else if (str_stdalloc.equalsIgnoreCase("off") || str_stdalloc.equalsIgnoreCase("false")
               || str_stdalloc.equalsIgnoreCase("n"))
      {
        stdalloc = 0;
      }
      else
      {
        System.out.println ("Error: invalid option value in stdalloc !");
        System.exit (0);
      }
    }

    str_strict = System.getProperty("sablevm.jdwp.strict");
    if (str_strict != null)
    {
      if (str_strict.equalsIgnoreCase("on") || str_strict.equalsIgnoreCase("true")
          || str_strict.equalsIgnoreCase("y"))
      {
        strict = 1;
      }
      else if (str_strict.equalsIgnoreCase("off") || str_strict.equalsIgnoreCase("false")
               || str_strict.equalsIgnoreCase("n"))
      {
        strict = 0;
      }
      else
      {
        System.out.println ("Error: invalid option value in strict !");
        System.exit (0);
      }
    }

    str_suspend = System.getProperty("sablevm.jdwp.suspend");
    if (str_suspend != null)
    {
      if (str_suspend.equalsIgnoreCase("on") || str_suspend.equalsIgnoreCase("true")
          || str_suspend.equalsIgnoreCase("y"))
      {
        suspend = 1;
      }
      else if (str_suspend.equalsIgnoreCase("off") || str_suspend.equalsIgnoreCase("false")
               || str_suspend.equalsIgnoreCase("n"))
      {
        suspend = 0;
      }
      else
      {
        System.out.println ("Error: invalid option value in suspend !");
        System.exit (0);
      }
    }


    launch = System.getProperty("sablevm.jdwp.launch");


    onthrow = System.getProperty("sablevm.jdwp.onthrow");


    start = System.getProperty("sablevm.jdwp.start");

    helper = new StartAppHelper (start, args, suspend);
    if (helper.setup() == false)
    {
      System.out.println ("Error: an error occured during debugged class setup!");
      System.exit (0);
    }
    jdwpstart.load
    (transport, server, address, launch, onthrow, onuncaught,
     stdalloc, strict, suspend, port, start, thread, args);
  }
}


