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

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

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

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

coral::Language* uml14;

static void recursivelyCreate(coral::Element* ns, int level, int maxlevel, int children) {
	if (level >= maxlevel) return;
	for (int i = 0; i < children; ++i) {
		std::string name;
		char buf[16];
		snprintf(buf, 16, "%d", i);
		name += "Package ";
		name += buf;
		coral::Atom* _child = uml14->getElement("Package")->newAtom();
		coral::Element* child = static_cast<coral::Element*>(_child);

		dynamic_cast<coral::ElementString*>(child->__getSlotByName__("name")[0])->__setString__(coral::unicodestring(name, true));
		ns->__getSlotByName__("ownedElement").insert(child);
		recursivelyCreate(child, level+1, maxlevel, children);
	}
}

int main() {
	coral::init_coral_framework();
	coral::autounref<coral::Language> _uml14
		= coral::Language::__getLanguage__("UML", 1, 4);
	uml14 = _uml14.get();
	coral::Atom* _m = uml14->getElement("Model")->newAtom();
	coral::Element* m = static_cast<coral::Element*>(_m);

	int levels = 6;
	int children = 6;
	recursivelyCreate(m, 0, levels, children);

	std::ofstream out("out.xmi", std::ios_base::out|std::ios_base::trunc);

	struct timeval start_time;
	struct timeval end_time;
	gettimeofday(&start_time, NULL);
	coral::Sequence o;
	o.append(m);
	coral::io::saveDocument_raw(out, &o, "1.2");
	gettimeofday(&end_time, NULL);
	std::cout
	  << "Time to save 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 << "Done!" << std::endl;

	return 0;
}
