package tester;

import java.lang.reflect.*;

/**
 * Copyright 2008 Viera K. Proulx, Matthias Felleisen
 * This program is distributed under the terms of the 
 * GNU Lesser General Public License (LGPL)
 */

/**
 * <P>The <code>main</code> method in this class uses the command-line 
 * argument to determine the class that contains the test cases. 
 * If no class name is given "Examples" is assumed.</P> 
 * <P>The main method instantiates 
 * this class and invokes the <CODE>{@link Tester Tester}</CODE> 
 * on this new instance.</P>
 * 
 * @author Viera K. Proulx, Matthias Felleisen
 * @since 3 March 2008, 16 October 2008
 *
 */
public class Main{

  /**
   * Method that creates an instance of the <code>Tester</code> and an
   * instance of the class that defines the tests, invokes the test
   * evaluation by the <code>Tester</code>, and reports the results.
   * 
   * @param argv [optional] the name of the class that defines the tests
   */
  public static void main(String argv[]){
    
    // get the name of the class that defines the tests
    String classname;
    if ((argv == null) || (Array.getLength(argv) == 0))
      classname = "Examples";
    else
      classname = argv[0];

    // construct an instance of the class that defines the tests
    Object o = null;
    Class<?> examples;
    try {
      examples = Class.forName(classname);

      try{   
        Constructor<?> construct = examples.getDeclaredConstructor();
        construct.setAccessible(true);
        o = construct.newInstance();

        System.out.println("Tester Results");        
      }
      catch (NoSuchMethodException ex){
        System.out.println("no default costructor: " + ex.getMessage());
      }
      catch (InvocationTargetException ex){
        System.out.println("Invocation: " + ex.getMessage());
      }
      
      // run tests if the instance was successfully constructed
      if (o != null){
        Tester t = new Tester();
        t.runAnyTests(o);
      }

      // report the problem if an instance of the class that defines the tests
      // has not been successfully constructed
      else
        throw new RuntimeException("o is null");
    }
    // report errors:
    // wrong classname:
    catch (InstantiationException c) {
      System.out.println("Cannot construct an instance of " + classname);
    }    
    catch (IllegalAccessException c) {
      System.out.println(c);
    }    
    catch (ClassNotFoundException c) {
      System.out.println(classname + " class doesn't exist");
    }     
    catch (ClassCastException c) {
      System.out.println("Examples is expected to extend Main");
    }
    // finish up
    finally {
      System.out.println(" ");
    }
  }
}


