/*=====================================================================*/
/*    serrano/prgm/project/bigloo/runtime/cslib/dlopen.cs              */
/*    -------------------------------------------------------------    */
/*    Author      :  Manuel Serrano                                    */
/*    Creation    :  Mon Dec 11 15:42:09 2000                          */
/*    Last change :  Fri Jul  6 15:13:53 2001 (serrano)                */
/*    Copyright   :  2000-01 Manuel Serrano                            */
/*    -------------------------------------------------------------    */
/*    Dynamic class loading for the .Net back-end.                     */
/*=====================================================================*/
using System;
using System.Reflection;

namespace bigloo
{
  /*---------------------------------------------------------------------*/
  /*    dlopen ...                                                       */
  /*---------------------------------------------------------------------*/
  public abstract class dlopen
  {
    private const String NO_ERROR_YET= "No error (yet)";

    private static String bgl_dload_error= NO_ERROR_YET;

    static String suffix( byte[]  filename )
    {
      int          len= filename.Length;
      int          i;

      for ( i= len-1 ; (0 <= i) && (filename[i] != '.') ; --i )
        ;

      if (0 <= i)
        return foreign.newstring( filename, 0, i );
      else
        return foreign.newstring( filename );
    }

    public static int dload( byte[]  filename,
                             byte[]  init_sym ) 
    {
      bgl_dload_error= NO_ERROR_YET;

      try
      {
        // !!!!! faut-il réellement virer le suffixe ?????
        String     type_name= suffix( filename );

        Console.Error.WriteLine( "~~~~~[dload::dload( {0}, {1} ) :  Type.GetType( {2}, true, false )",
                                 foreign.newstring( filename ),
                                 foreign.newstring( init_sym ),
                                 type_name );

        Type       type= Type.GetType( type_name, true, false );

        if (!type.IsClass)
        {
          /***** type is not a class *****/
          bgl_dload_error= ("Type [" + type_name + "] is not a class.");
          return 1;
        }

        Console.Error.WriteLine( "~~~~~[dload::dload( {0}, {1} ) :  type.GetMethod( {2} )",
                                 foreign.newstring( filename ),
                                 foreign.newstring( init_sym ),
                                 foreign.newstring( init_sym ) );

        MethodInfo      init= type.GetMethod( foreign.newstring( init_sym ) );

        Console.Error.WriteLine( "~~~~~[dload::dload( {0}, {1} ) :  init.Invoke( null, null )",
          foreign.newstring( filename ),
          foreign.newstring( init_sym ) );

        init.Invoke( null, null );

        Console.Error.WriteLine( "~~~~~[dload::dload( {0}, {1} ) :  done.",
          foreign.newstring( filename ),
          foreign.newstring( init_sym ) );

        return 0;
      }
      catch (Exception e)
      {
        bgl_dload_error= e.Message;
        return 1;
      }
    }

    public static byte[] dload_error()
    {
      return foreign.getbytes( bgl_dload_error );
    }
  }
}
