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

#include <coral/core/io/xmi_writer_1.h>

#include <iostream>
#include <fstream>
#include <cmath>

#include <sys/time.h>
#include <unistd.h>

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

	struct timeval start_time;
	struct timeval end_time;
	gettimeofday(&start_time, NULL);
	coral::Element* root = coral::io::loadModel("test.xmi");
	coral_assert(root);
	gettimeofday(&end_time, NULL);
	std::cout
	  << "Time to load was "
	  << static_cast<float>(((end_time.tv_sec - start_time.tv_sec) * 1000000L
	      + (end_time.tv_usec - start_time.tv_usec))) / 1000000L
	  << std::endl;

	std::cout << "Name of model is " << dynamic_cast<coral::ElementString*>(root->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(!strcmp(dynamic_cast<coral::ElementString*>(root->__getSlotByName__("name")[0])->__getString__().toUTF8().c_str(), "mymodelname"));
	std::cout << "Visibility is " << dynamic_cast<coral::ElementEnumeration*>(root->__getSlotByName__("visibility")[0])->__getEValueByName__() << std::endl;
	coral_assert(!strcmp(dynamic_cast<coral::ElementEnumeration*>(root->__getSlotByName__("visibility")[0])->__getEValueByName__().toUTF8().c_str(), "private"));
	std::cout << "Child is " << root->__getSlotByName__("ownedElement")[0] << std::endl;
	coral::Atom* _p = root->__getSlotByName__("ownedElement")[0];
	coral::Element* p = dynamic_cast<coral::Element*>(_p);
	coral_assert(p);
	coral_assert(p != root);
	coral_assert(p->__type__() == uml14->getElement("Package").get());
	coral_assert(root->__type__() == uml14->getElement("Model").get());
	coral::Atom* _c = p->__getSlotByName__("ownedElement")[0];
	coral::Element* c = dynamic_cast<coral::Element*>(_c);
	coral_assert(c);
	std::cout << c->__str__() << std::endl;
	coral_assert(c->__type__() == uml14->getElement("Class").get());
	coral_assert(!strcmp(dynamic_cast<coral::ElementString*>(p->__getSlotByName__("name")[0])->__getString__().toUTF8().c_str(), "mypackage"));
	coral_assert(!strcmp(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__().toUTF8().c_str(), "myclass"));
	std::cout << "Done!" << std::endl;

	coral::io::saveModel("out-load-and-saved.xmi", root);

	return 0;
}
