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

#include <iostream>


#include <unistd.h>

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

	int i = coral::all_modelelements_size();

	coral::Atom* _c = uml14->getElement("Class")->newAtom();
	coral::Atom* _m = uml14->getElement("Model")->newAtom();
	coral::Element* c = static_cast<coral::Element*>(_c);
	coral::Element* m = static_cast<coral::Element*>(_m);

	m->__getSlotByName__("ownedElement").insert(c);

	std::cout << "We have a model and a class." << std::endl
		  << "They are connected, so even though the program" << std::endl
		  << "will unref() both elements, we will have a loop" << std::endl
		  << "(refcount is still 1 for both elements) and the elements" << std::endl
		  << "will not be deleted" << std::endl << std::endl;
	
	std::cout << "But now we will call the Garbage Collector" << std::endl;

	coral_assert(coral::all_modelelements_size() == i + 2);
	coral::garbage_collect();
	coral_assert(coral::all_modelelements_size() == i + 2);

	c->unref();
	coral::garbage_collect();
	coral_assert(coral::all_modelelements_size() == i + 2);

	coral::Slot& mf = m->__getSlotByName__("ownedElement");
	coral::Iterator p(mf);
	coral::ref_counted* c2 = p.next();
	c2->ref();

	m->unref();
	coral::garbage_collect();
	coral_assert(coral::all_modelelements_size() == i + 2);

	c2->unref();
	coral::garbage_collect();
	coral_assert(coral::all_modelelements_size() == i);
	std::cout << "Tada! It deleted the elements!" << std::endl;



	return 0;
}
