package com.orientechnologies.orient.core.metadata.schema;

import java.util.List;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static org.testng.Assert.*;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.sql.OCommandSQL;

public class TestMultiSuperClasses {
	private ODatabaseDocumentTx db;

	  @BeforeMethod
	  public void setUp() {
	    db = new ODatabaseDocumentTx("memory:" + TestMultiSuperClasses.class.getSimpleName());
	    if (db.exists()) {
	      db.open("admin", "admin");
	    } else
	      db.create();
	  }

	  @AfterMethod
	  public void after() {
	    db.close();
	  }
	  
	  @Test
	  public void testClassCreation()
	  {
		  final OSchema oSchema = db.getMetadata().getSchema();

		  OClass aClass = oSchema.createAbstractClass("javaA");
		  OClass bClass = oSchema.createAbstractClass("javaB");
		  OClass cClass = oSchema.createClass("javaC", aClass,bClass);
		  List<? extends OClass> superClasses;
		  //Run twice to be sure after schema reload
		  for(int i=0;i<2;i++)
		  {
			  superClasses = cClass.getSuperClasses();
			  assertTrue(superClasses.contains(aClass));
			  assertTrue(superClasses.contains(bClass));
			  assertTrue(cClass.isSubClassOf(aClass));
			  assertTrue(cClass.isSubClassOf(bClass));
			  assertTrue(aClass.isSuperClassOf(cClass));
			  assertTrue(bClass.isSuperClassOf(cClass));
			  oSchema.reload();
		  }
	  }
	  
	  @Test
	  public void testSql()
	  {
		  final OSchema oSchema = db.getMetadata().getSchema();

		  OClass aClass = oSchema.createAbstractClass("sqlA");
		  OClass bClass = oSchema.createAbstractClass("sqlB");
		  OClass cClass = oSchema.createClass("sqlC");
		  db.command(new OCommandSQL("alter class sqlC superclasses sqlA, sqlB")).execute();
		  oSchema.reload();
		  assertTrue(cClass.isSubClassOf(aClass));
		  assertTrue(cClass.isSubClassOf(bClass));
		  db.command(new OCommandSQL("alter class sqlC superclass sqlA")).execute();
		  oSchema.reload();
		  assertTrue(cClass.isSubClassOf(aClass));
		  assertFalse(cClass.isSubClassOf(bClass));
		  db.command(new OCommandSQL("alter class sqlC superclass +sqlB")).execute();
		  oSchema.reload();
		  assertTrue(cClass.isSubClassOf(aClass));
		  assertTrue(cClass.isSubClassOf(bClass));
		  db.command(new OCommandSQL("alter class sqlC superclass -sqlA")).execute();
		  oSchema.reload();
		  assertFalse(cClass.isSubClassOf(aClass));
		  assertTrue(cClass.isSubClassOf(bClass));
	  }
	  
	  @Test
	  public void testCreationBySql()
	  {
		  final OSchema oSchema = db.getMetadata().getSchema();

		  db.command(new OCommandSQL("create class sql2A abstract")).execute();
		  db.command(new OCommandSQL("create class sql2B abstract")).execute();
		  db.command(new OCommandSQL("create class sql2C extends sql2A, sql2B abstract")).execute();
		  oSchema.reload();
		  OClass aClass = oSchema.getClass("sql2A");
		  OClass bClass = oSchema.getClass("sql2B");
		  OClass cClass = oSchema.getClass("sql2C");
		  assertNotNull(aClass);
		  assertNotNull(bClass);
		  assertNotNull(cClass);
		  assertTrue(cClass.isSubClassOf(aClass));
		  assertTrue(cClass.isSubClassOf(bClass));
	  }
}

@@ -783,38 +783,32 @@
 tion()%0A%09  %7B%0A%09%09  
-final 
 OSchema oSchema 
@@ -964,192 +964,667 @@
 %09%09  
-OClass cClass = oSchema.createClass(%22javaC%22, aClass,bClass);%0A%09%09  List%3C? extends OClass%3E superClasses;%0A%09%09  //Run twice to be sure after schema reload%0A%09%09  for(int i=0;i%3C2;i++
+aClass.createProperty(%22property%22, OType.INTEGER);%0A%09%09  bClass.createProperty(%22property%22, OType.DOUBLE);%0A%09%09  OClass cClass = oSchema.createClass(%22javaC%22, aClass,bClass);%0A%09%09  testClassClreationBranch(aClass, bClass, cClass);%0A%09%09  oSchema.reload();%0A%09%09  testClassClreationBranch(aClass, bClass, cClass);%0A%09%09  oSchema = db.getMetadata().getImmutableSchemaSnapshot();%0A%09%09  aClass = oSchema.getClass(%22javaA%22);%0A%09%09  bClass = oSchema.getClass(%22javaB%22);%0A%09%09  cClass = oSchema.getClass(%22javaC%22);%0A%09%09  testClassClreationBranch(aClass, bClass, cClass);%0A%09  %7D%0A%09  %0A%09  private void testClassClreationBranch(OClass aClass, OClass bClass, OClass cClass
 )%0A
-%09
 %09  %7B%0A%09%09
-%09
  
+ List%3C? extends OClass%3E
  sup
@@ -1661,17 +1661,16 @@
 sses();%0A
-%09
 %09%09  asse
@@ -1700,33 +1700,32 @@
 tains(aClass));%0A
-%09
 %09%09  assertTrue(s
@@ -1749,33 +1749,32 @@
 ins(bClass));%0A%09%09
-%09
   assertTrue(cCl
@@ -1792,33 +1792,32 @@
 assOf(aClass));%0A
-%09
 %09%09  assertTrue(c
@@ -1837,33 +1837,32 @@
 assOf(bClass));%0A
-%09
 %09%09  assertTrue(a
@@ -1894,17 +1894,16 @@
 ss));%0A%09%09
-%09
   assert
@@ -1945,34 +1945,228 @@
 ;%0A%09%09
-%09  oSchema.reload();%0A%09%09  %7D
+  %0A%09%09  OProperty property = cClass.getProperty(%22property%22);%0A%09%09  assertEquals(OType.INTEGER, property.getType());%0A%09%09  property = cClass.propertiesMap().get(%22property%22);%0A%09%09  assertEquals(OType.INTEGER, property.getType());
 %0A%09  

Add testcase for inheritance of properties with the same name