/*******************************************************************************
 *	GenBDataMySql.cc	BEAM Data output
 *			T.Barnaby,	BEAM Ltd,	12/9/03
 *******************************************************************************
 */
#define	DEBUG	1

#include <stdio.h>
#include <stdarg.h>
#include <strings.h>
#include <GenBDataMySql.h>
#include <bidl.h>

BString GenBDataMySql::getTypeName(BString typeName){
	if(typeName == "Int32")		return "Int";
	else if(typeName == "String")	return "Text";
	else if(typeName == "Date")	return "Date";
	else if(typeName == "DateTime")	return "DateTime";
	else return typeName;
}

BError GenBDataMySql::produceType(BString& s, BString name, Type* t){
	BError		err;
	BString		typeName;
	BString		n;
	BIter		i;
	BList<Node*>*	nl;
	Type*		dt;
	Type*		mt;

//	printf("produceType: %s\n", t->name().retStr());
	if(dt = t->derived()){
		produceType(s, name, dt);
	}
	if(name.len())
		name = name + "_";
	nl = &t->node()->nodes();
	for(nl->start(i); !nl->isEnd(i); nl->next(i)){
		n = name + nl->get(i)->node(1)->name();
		typeName = nl->get(i)->node(0)->name();
//		printf("ProduceMember: %s %s\n", typeName.retStr(), n.retStr());
		if(mt = gtypelist.search(typeName)){
			produceType(s, n, mt);
		}
		else {
			if(s.len())
				s = s + ", ";
			if(typeName == "Id"){
				s = s + "`" + n + "` " + "Int" + " not null auto_increment primary key";
			}
			else if(typeName == "List"){
				s = s + "`" + n + "` " + "Text";
			}
			else {
				s = s + "`" + n + "` " + getTypeName(typeName);
			}
		}
	}
	return err;
}

BError GenBDataMySql::produceImp(Node* n){
	BError		err;
	BString		s;
	BIter		i;
	Type*		tp;
	int		typeId;

	switch(n->nodeType()){
	case Node::TMODULE:
		omodule = n->name();
//		ofileImp.writeLine(BString("database ") + omodule + "\n");
		for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
			produceImp(n->nodes()[i]);
		}
		break;
	case Node::TLIST:
		for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
			produceImp(n->nodes()[i]);
		}
		break;
		
	case Node::TTYPEDOMAIN:
		otypeDomain = atoi(n->name());
		break;

	case Node::TSTRUCT:
		s = "";
		if((n->name() == "BObjData") || (n->name() == "BObject"))
			return err;
		if(tp = gtypelist.search(n->name())){
			produceType(s, "", tp);
		}
		else {
			err.set(1, BString("Unknown type: ") + n->name());
			return err;
		}
		typeId = (otypeDomain << 16) | (otypeNum);
		s = BString("type Int not null, ") + s;
		ofileImp.writeLine(n->name() + " (" + s + ")\n");
		otypeNum++;
		break;
	default:
		break;
	}
	return err;
}

BError GenBDataMySql::produceHeaderImp(){
	BError	err;

	return err;
}
BError GenBDataMySql::produceTrailerImp(){
	BError	err;
	
	return err;
}

GenBDataMySql::GenBDataMySql(){
	otypeDomain = 0;
	otypeNum = 1;
}

GenBDataMySql::~GenBDataMySql(){
}

BError GenBDataMySql::produce(Node* n, BString fileName){
	BError	err;
	
//	dprintf("GenBDataMySql::produce: %p\n", n);

	ofileName = fileName;
	ofileImp.open(ofileName + ".mysql", "w");
	
	// File Headers
	produceHeaderImp();
	
	// Generate code
	produceImp(n);

	// Generate trailers
	produceTrailerImp();
	ofileImp.close();

	return err;
}
