/* Test the Modern GNU Objective-C Runtime API.

  This is test 'class', covering all functions starting with 'class'.
  Tests calling the functions with a meta class as argument are covered
  in the separate file, gnu-api-2-class-meta.m.  */

/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-additional-options "-Wno-objc-root-class" } */
/* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */

/* To get the modern GNU Objective-C Runtime API, you include
   objc/runtime.h.  */
#include <objc/runtime.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

@interface MyRootClass
{ Class isa; }
+ alloc;
- init;
+ initialize;
@end

@implementation MyRootClass
+ alloc { return class_createInstance (self, 0); }
- init  { return self; }
+ initialize { return self; }
@end

@protocol MyProtocol
- (id) variable;
@end

@protocol MySecondProtocol
- (id) setVariable: (id)value;
@end

@interface MySubClass : MyRootClass <MyProtocol>
{ id variable_ivar; }
- (void) setVariable: (id)value;
- (id) variable;
@end

@implementation MySubClass
- (void) setVariable: (id)value { variable_ivar = value; }
- (id) variable { return variable_ivar; }
@end

@interface MyOtherSubClass : MySubClass
@end

@implementation MyOtherSubClass
@end

@interface DifferentClass : MyRootClass
- (id) myClass;
- (id) self;
@end

@implementation DifferentClass
- (id) myClass { return object_getClass (self); }
- (id) self { return self; }
@end

@interface MySubClass (MySelf)
- (id) mySelf;
@end

/* Hack to calculate the log2 of a byte alignment.  */
unsigned char
log_2_of (unsigned int x)
{
  unsigned char result = 0;

  /* We count how many times we need to divide by 2 before we reach 1.
     This algorithm is good enough for the small numbers (such as 8,
     16 or 64) that we have to deal with.  */
  while (x > 1)
    {
      x = x / 2;
      result++;
    }

  return result;
}

int main(int argc, void **args)
{
  /* Functions are tested in alphabetical order.  */

  printf ("Testing class_addIvar ()...\n");
  {
    Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);

    if (new_class == Nil)
      abort ();
    
    if (! class_addIvar (new_class, "variable2_ivar", sizeof (id),
			 log_2_of (__alignof__ (id)), @encode (id)))
      abort ();

    if (! class_addIvar (new_class, "variable3_ivar", sizeof (unsigned char),
			 log_2_of (__alignof__ (unsigned char)), @encode (unsigned char)))
      abort ();

    if (! class_addIvar (new_class, "variable4_ivar", sizeof (unsigned long),
			 log_2_of (__alignof__ (unsigned long)), @encode (unsigned long)))
      abort ();

    objc_registerClassPair (new_class);    

    {
      MySubClass *o = [[(Class)objc_getClass ("MySubSubClass") alloc] init];
      Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar");
      Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar");
      Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar");

      if (variable2 == NULL  || variable3 == NULL  ||  variable4 == NULL)
	abort ();
      
      if (strcmp (ivar_getName (variable2), "variable2_ivar") != 0)
	abort ();

      if (strcmp (ivar_getName (variable3), "variable3_ivar") != 0)
	abort ();

      if (strcmp (ivar_getName (variable4), "variable4_ivar") != 0)
	abort ();

      {
	unsigned char *var3 = (unsigned char *)((char *)o + ivar_getOffset (variable3));
	unsigned long *var4 = (unsigned long *)((char *)o + ivar_getOffset (variable4));

	object_setIvar (o, variable2, new_class);
	*var3 = 230;
	*var4 = 89000L;

	if (object_getIvar (o, variable2) != new_class)
	  abort ();

	if (*var3 != 230)
	  abort ();

	if (*var4 != 89000L)
	  abort ();
      }
    }
  }

  printf ("Testing class_addMethod ()...\n");
  {
    Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass2", 0);
    Method method1 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
    Method method2 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (variable));

    if (new_class == Nil)
      abort ();
    
    if (! class_addIvar (new_class, "variable_ivar", sizeof (id),
			 log_2_of (__alignof__ (id)), @encode (id)))
      abort ();

    if (! class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method1),
			   method_getTypeEncoding (method1)))
      abort ();

    if (! class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
			   method_getTypeEncoding (method2)))
      abort ();

    /* Test that if the method already exists in the class,
       class_addMethod() returns NO.  */
    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
			 method_getTypeEncoding (method2)))
      abort ();

    objc_registerClassPair (new_class);    

    /* Now, MySubClass2 is basically the same as MySubClass!  We'll
       use the variable and setVariable: methods on it.  */
    {
      MySubClass *o = (MySubClass *)[[(Class)objc_getClass ("MySubClass2") alloc] init];

      [o setVariable: o];

      if ([o variable] != o)
	abort ();
    }

    /* Now, try that if you take an existing class and try to add an
       already existing method, class_addMethod returns NO.  This is
       subtly different from before, when 'new_class' was still in
       construction.  Now it's a real class and the libobjc internals
       differ between the two cases.  */
    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
			 method_getTypeEncoding (method2)))
      abort ();
  }

  printf ("Testing class_addProtocol ()...\n");
  {
    if (!class_addProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
      abort ();
    
    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
      abort ();

    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
      abort ();
  }

  printf ("Testing class_conformsToProtocol ()...\n");
  {
    if (class_conformsToProtocol (objc_getClass ("MyRootClass"), @protocol (MyProtocol)))
      abort ();

    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
      abort ();

    /* Test that class_conformsToProtocol checks the class, but not
       superclasses.  */
    if (class_conformsToProtocol (objc_getClass ("MyOtherSubClass"), @protocol (MyProtocol)))
      abort ();
  }

  printf ("Testing class_copyIvarList ()...\n");
  {
    unsigned int count;
    Ivar * list = class_copyIvarList (objc_getClass ("MySubClass"), &count);

    if (count != 1)
      abort ();

    if (strcmp (ivar_getName (list[0]), "variable_ivar") != 0)
      abort ();
    
    if (list[1] != NULL)
      abort ();
  }

  printf ("Testing class_copyIvarList () on class with no instance variables...\n");
  {
    unsigned int count;
    Ivar * list = class_copyIvarList (objc_getClass ("MyOtherSubClass"),
                                      &count);

    if (count != 0)
      abort ();
    
    if (list != NULL)
      abort ();
  }

  printf ("Testing class_copyMethodList ()...\n");
  {
    unsigned int count;
    Method * list = class_copyMethodList (objc_getClass ("MySubClass"), &count);

    if (count != 2)
      abort ();
    
    if (! ((strcmp (sel_getName (method_getName (list[0])), "variable") == 0
	    && strcmp (sel_getName (method_getName (list[1])), "setVariable:") == 0)
	   || (strcmp (sel_getName (method_getName (list[0])), "setVariable:") == 0
	       && strcmp (sel_getName (method_getName (list[1])), "variable") == 0)))
      abort ();
    
    if (list[2] != NULL)
      abort ();
  }

  /* TODO: Test new ABI (when available).  */
  printf ("Testing class_copyPropertyList ()...\n");
  {
    unsigned int count;
    objc_property_t * list = class_copyPropertyList (objc_getClass ("MySubClass"), &count);

    if (count != 0  ||  list != NULL)
      abort ();
  }

  printf ("Testing class_copyProtocolList ()...\n");
  {
    unsigned int count;
    Protocol ** list = class_copyProtocolList (objc_getClass ("MySubClass"), &count);

    /* Remember that we added MySecondProtocol in the test above.  */
    if (count != 2)
      abort ();

    if (! ((strcmp (protocol_getName (list[0]), "MyProtocol") == 0
	    && strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0)
	   || (strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0
	       && strcmp (protocol_getName (list[1]), "MyProtocol") == 0)))
      abort ();
    
    if (list[2] != NULL)
      abort ();
  }

  printf ("Testing class_createInstance ()...\n");
  {
    MySubClass *object = [[MySubClass alloc] init];

    [object setVariable: object];
    if ([object variable] != object)
      abort ();
  }

  printf ("Testing class_getClassMethod ()...\n");
  {
    Method method = class_getClassMethod (objc_getClass ("MySubClass"),
					  @selector(alloc));

    if (method == NULL)
      abort ();

    if (strcmp (sel_getName (method_getName (method)), "alloc") != 0)
      abort ();

    if (class_getClassMethod (objc_getClass ("MySubClass"), 
			      @selector(variable)))
      abort ();
  }

  printf ("Testing class_getClassVariable ()...\n");
  {
    if (class_getClassVariable (objc_getClass ("MySubClass"), "variable_ivar"))
      abort ();
  }

  printf ("Testing class_getInstanceMethod ()...\n");
  {
    Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), 
					     @selector(variable));

    if (method == NULL)
      abort ();

    if (strcmp (sel_getName (method_getName (method)), "variable") != 0)
      abort ();

    if (class_getInstanceMethod (objc_getClass ("MySubClass"), 
				 @selector(alloc)))
      abort ();
  }

  printf ("Testing class_getInstanceSize ()...\n");
  {
    if (class_getInstanceSize (objc_getClass ("MyRootClass")) != sizeof (struct objc_object))
      abort ();
  }

  printf ("Testing class_getInstanceVariable ()...\n");
  {
    Ivar variable = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar");

    if (variable == NULL)
      abort ();

    if (strcmp (ivar_getName (variable), "variable_ivar") != 0)
      abort ();

    if (class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar_no"))
      abort ();
  }

  printf ("Testing class_getIvarLayout ()...\n");
  {
    if (class_getIvarLayout (objc_getClass ("MyRootClass")) != NULL)
      abort ();
  }

  printf ("Testing class_getMethodImplementation ()...\n");
  {
    MySubClass *object = [[MySubClass alloc] init];
    IMP imp = class_getMethodImplementation (objc_getClass ("MySubClass"), 
					     @selector(variable));

    if (imp == NULL)
      abort ();

    [object setVariable: object];

    if ((*imp)(object, @selector(variable)) != object)
      abort ();
  }

  /* This function does not exist with the GNU runtime.  */
  /* printf ("Testing class_getMethodImplementation_stret ()...\n"); */

  printf ("Testing class_getName ()...\n");
  {
    if (strcmp (class_getName (objc_getClass ("MyRootClass")),
		"MyRootClass") != 0)
      abort ();
  }

  /* TODO: Test new ABI (when available).  */
  printf ("Testing class_getProperty ()...\n");
  {
    if (class_getProperty (objc_getClass ("MyRootClass"), "property") != NULL)
      abort ();
  }

  printf ("Testing class_getSuperclass ()...\n");
  {
    MySubClass *object = [[MySubClass alloc] init];
    if (class_getSuperclass (object_getClass (object)) != objc_getClass ("MyRootClass"))
      abort ();

    /* Test that it works on a newly created, but not registered, class.  */
    {
      Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass3", 0);

      if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
	abort ();
    }
  }

  printf ("Testing class_getVersion ()...\n");
  {
    if (class_getVersion (objc_getClass ("MySubClass")) != 0)
      abort ();
  }

   printf ("Testing class_getWeakIvarLayout ()...\n");
  {
    if (class_getWeakIvarLayout (objc_getClass ("MyRootClass")) != NULL)
      abort ();
  }

  printf ("Testing class_isMetaClass ()...\n");
  {
    MySubClass *object = [[MySubClass alloc] init];
    if (class_isMetaClass (object_getClass (object)) 
	|| ! class_isMetaClass (object_getClass (object_getClass (object))))
      abort ();
  }

  printf ("Testing class_replaceMethod ()...\n");
  {
    Method new_method = class_getInstanceMethod (objc_getClass ("DifferentClass"),
						 @selector (myClass));
    Method old_method = class_getInstanceMethod (objc_getClass ("MySubClass"),
						 @selector (variable));
    const char *new_types = method_getTypeEncoding (new_method);
    IMP new_imp = method_getImplementation (new_method);
    const char *old_types = method_getTypeEncoding (old_method);
    IMP old_imp = class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
				       method_getImplementation (new_method),
				       method_getTypeEncoding (new_method));
    MySubClass *o = [[MySubClass alloc] init];

    [o setVariable: o];

    /* Try the new method implementation.  */
    if ([o variable] != objc_getClass ("MySubClass"))
      abort ();

    /* Put the original method back.  */
    class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
			 old_imp, old_types);

    /* Test it's back to what it was.  */
    if ([o variable] != o)
      abort ();    

    {
      DifferentClass *o = [[DifferentClass alloc] init];

      /* Finally, try adding a new method.  */
      class_replaceMethod (objc_getClass ("DifferentClass"), @selector (mySelf),
			   new_imp, new_types);
      
      if ([(MySubClass*)o mySelf] != objc_getClass ("DifferentClass"))
	abort ();
    }
  }

  printf ("Testing class_respondsToSelector ()...\n");
  {
    if (! class_respondsToSelector (objc_getClass ("MySubClass"), @selector(setVariable:)))
      abort ();

    if (class_respondsToSelector (objc_getClass ("MyRootClass"), @selector(setVariable:)))
      abort ();
  }

  /* This is not really implemented with the GNU runtime.  */
  /* printf ("Testing class_setIvarLayout ()...\n"); */

  printf ("Testing class_setVersion ()...\n");
  {
    class_setVersion (objc_getClass ("MySubClass"), 45);
    
    if (class_getVersion (objc_getClass ("MySubClass")) != 45)
      abort ();

    class_setVersion (objc_getClass ("MySubClass"), 46);

    if (class_getVersion (objc_getClass ("MySubClass")) != 46)
      abort ();
  }

  /* This is not really implemented with the GNU runtime.  */
  /* printf ("Testing class_setWeakIvarLayout ()...\n"); */

  return 0;
}
