#include <coral/core/Element.h>
#include <coral/core/ElementDefinition.h>

#include <iostream>
#include <unistd.h>

int main() {
	coral::init_coral_framework();
	coral::autounref<coral::Language>
		uml14 = coral::Language::__getLanguage__("UML", 1, 4);

/*
 * Number of objects. This is the main parameter of this benchmark
 */
	int size = 1200;
	
/*
 * it is not realistic to have an association with thousands of elements
 * maxAssocSize limits the number of elements per association end
 */
	int maxAssocSize = 50;

	std::cout << "foo1" << std::endl;
	coral::Element* m = static_cast<coral::Element*>(uml14->getElement("Model")->newAtom());
	coral_assert(m->get_ref_count() == 1);
	std::cout << "foo2" << std::endl;
	coral::Element* obj[size];

	coral::autounref<coral::AbstractElementDefinition>
		Class = uml14->getElement("Class");

	std::cout << "Creating" << size << "objects" << std::endl;
	for (int i = 0; i < size; ++i) {
		obj[i] = static_cast<coral::Element*>(Class->newAtom());
		coral_assert(obj[i]->get_ref_count() == 1);
	}


	std::cout << "Setting attributes. maxAssocSize=" << maxAssocSize << std::endl;

/*
 * Well, this isn't /the/ optimal code,
 * but basically that which we could at best get in Python
 */

	int r=0;
	coral::Slot& modelf = m->__getSlotByName__("ownedElement");
	for (int i = 0; i < size; ++i) {
#if 0
		obj[i]->__getSlotByNameInsert__("namespace", m);
		obj[i]->__getSlotByNameInsert__("namespace", NULL);
		obj[i]->__getSlotByNameInsert__("namespace", m);
		coral::Element* x = obj[i]->__getSlotByName__("namespace").__getitem__(0);
		if (++r == maxAssocSize) {
			r=0;
			m->__getSlotByName__("ownedElement").resetSlot();
		}
#endif
		coral::Slot& objf = obj[i]->__getSlotByName__("namespace");
		objf.insert(m);
		objf.insert(NULL);
		objf.insert(m);
		coral::Atom* x = objf.__getitem__(0);
		if (++r == maxAssocSize) {
			r=0;
			modelf.resetSlot();
		}
	}
	m->unref();
	sleep(60);
	for (int i = 0; i < size; ++i) {
		obj[i]->unref();
	}
}
