/***************************************************************************
 $RCSfile: aqbanking3-tool.c,v $
 -------------------
 cvs         : $Id: aqbanking3-tool.c,v 1.2 2008/10/08 20:10:10 schlaile Exp $
 begin       : Tue May 03 2005
 copyright   : (C) 2005 by Martin Preuss, (C) 2008 by Peter Schlaile
 email       : martin@libchipcard.de      peter at schlaile dot de

 ***************************************************************************
 * This file is part of the project "AqBanking".                           *
 * Please see toplevel file COPYING of that project for license details.   *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <aqbanking/banking.h>
#include <gwenhywfar/cgui.h>
#include <aqbanking/jobgettransactions.h>
#include <aqbanking/jobgetbalance.h>
#include <aqbanking/jobgetstandingorders.h>
#include <aqbanking/jobgetdatedtransfers.h>
#include <aqbanking/banking_imex.h>

#include <gwenhywfar/logger.h>
#include <gwenhywfar/db.h>
#include <gwenhywfar/dbio.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/io_file.h>
#include <gwenhywfar/iomanager.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/text.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define AQT_LOGDOMAIN AQBANKING_LOGDOMAIN
#define I18N

int exec_joblist(AB_BANKING *ab, GWEN_DB_NODE *db, AB_JOB_LIST2 *jl)
{
	AB_IMEXPORTER_CONTEXT *ctx;
	int rv;
	GWEN_DB_NODE *dbCtx;
	const char *ctxFile;
	int fd;
	GWEN_IO_LAYER *io;
	GWEN_DBIO * dbio;

	ctxFile = GWEN_DB_GetCharValue(db, "ctxfile", 0, 0);

	ctx = AB_ImExporterContext_new();

	rv = AB_Banking_ExecuteJobs(ab, jl, ctx, 0);

	AB_Job_List2_FreeAll(jl);

	if (rv) {
		fprintf(stderr, "Error on executeQueue (%d)\n", rv);
		return 2;
	}

	dbCtx=GWEN_DB_Group_new("context");
	rv=AB_ImExporterContext_toDb(ctx, dbCtx);
	if (rv) {
		DBG_ERROR(AQT_LOGDOMAIN, "Error storing context: %d", rv);
		AB_ImExporterContext_free(ctx);
		return 4;
	}
	AB_ImExporterContext_free(ctx);

	if (ctxFile == 0) {
		fd=fileno(stdout);
	} else {
		fd=open(ctxFile, O_RDWR | O_CREAT | O_TRUNC,
			S_IRUSR | S_IWUSR
#ifdef S_IRGRP
			| S_IRGRP
#endif
#ifdef S_IWGRP
			| S_IWGRP
#endif
			);
	}

	if (fd < 0) {
		DBG_ERROR(AQT_LOGDOMAIN, "Error selecting output file: %s",
			  strerror(errno));
		return 4;
	} 

	dbio = GWEN_DBIO_GetPlugin("xmldb");
		
	io = GWEN_Io_LayerFile_new(-1, fd);
	GWEN_Io_Manager_RegisterLayer(io);

	if (GWEN_DBIO_Export(dbio, io, dbCtx, db, 
			     GWEN_DB_FLAGS_DEFAULT,
			     0, 2000)) {
		DBG_ERROR(AQT_LOGDOMAIN, "Error writing context");
		GWEN_DB_Group_free(dbCtx);
		GWEN_Io_Layer_Disconnect(
			io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
		GWEN_Io_Layer_free(io);
		return 4;
	}

	GWEN_Io_Layer_DisconnectRecursively(io, NULL, 0, 0, 30000);
	GWEN_Io_Layer_free(io);

	GWEN_DB_Group_free(dbCtx);
	
	return 0;
}



int request(AB_BANKING *ab, GWEN_DB_NODE *dbArgs, int argc, char **argv)
{
	AB_ACCOUNT_LIST2 *al;
	GWEN_DB_NODE *db;
	const char *s;
	int rv;
	int requests=0;
	int reqTrans=0;
	int reqBalance=0;
	int reqSto=0;
	int reqDT=0;
	GWEN_TIME *fromTime=0;
	GWEN_TIME *toTime=0;
	AB_JOB_LIST2 *jl;

	const GWEN_ARGS args[]={
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"bankId",                     /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"b",                          /* short option */
			"bank",                       /* long option */
			"Specify the bank code",      /* short description */
			"Specify the bank code"       /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"accountId",                  /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"a",                          /* short option */
			"account",                    /* long option */
			"Specify the account number",     /* short description */
			"Specify the account number"      /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"bankName",                   /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"N",                          /* short option */
			"bankname",                   /* long option */
			"Specify the bank name",      /* short description */
			"Specify the bank name"       /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"accountName",                /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"n",                          /* short option */
			"accountname",                    /* long option */
			"Specify the account name",     /* short description */
			"Specify the account name"      /* long description */
		},
		{
			0,                            /* flags */
			GWEN_ArgsType_Int,             /* type */
			"reqTrans",                   /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"transactions",               /* long option */
			"Request transactions",       /* short description */
			"Request transactions"        /* long description */
		},
		{
			0,                            /* flags */
			GWEN_ArgsType_Int,             /* type */
			"reqBalance",                 /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"balance",                    /* long option */
			"Request balance",            /* short description */
			"Request balance"             /* long description */
		},
		{
			0,                            /* flags */
			GWEN_ArgsType_Int,             /* type */
			"reqSto",                     /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"sto",                        /* long option */
			"Request standing orders",    /* short description */
			"Request standing orders"     /* long description */
		},
		{
			0,                            /* flags */
			GWEN_ArgsType_Int,             /* type */
			"reqDT",                      /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"dated",                      /* long option */
			"Request dated transfers",    /* short description */
			"Request dated transfers"     /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"fromDate",                   /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"fromdate",                   /* long option */
			"Specify the first date for which transactions are wanted (YYYYMMDD)", /* sh
												  ort */
			"Specify the first date for which transactions are wanted (YYYYMMDD)" /* lon
												 g */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"toDate",                     /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"todate",                     /* long option */
			"Specify the first date for which transactions are wanted (YYYYMMDD)", /* sh
												  ort */
			"Specify the first date for which transactions are wanted (YYYYMMDD)" /* lon
												 g */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"ctxFile",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"c",                          /* short option */
			"ctxfile",                    /* long option */
			"Specify the file to store the context in",   /* short description */
			"Specify the file to store the context in"      /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
			GWEN_ArgsType_Int,             /* type */
			"help",                       /* name */
			0,                            /* minnum */
			0,                            /* maxnum */
			"h",                          /* short option */
			"help",                       /* long option */
			"Show this help screen",      /* short description */
			"Show this help screen"       /* long description */
		}
	};
	
	db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
	rv=GWEN_Args_Check(argc, argv, 1,
			   0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/,
			   args,
			   db);
	if (rv==GWEN_ARGS_RESULT_ERROR) {
		fprintf(stderr, "ERROR: Could not parse arguments\n");
		return 1;
	}
	else if (rv==GWEN_ARGS_RESULT_HELP) {
		GWEN_BUFFER *ubuf;
		
		ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
		if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
			fprintf(stderr, "ERROR: Could not create help string\n");
			return 1;
		}
		fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
		GWEN_Buffer_free(ubuf);
		return 0;
	}
	reqTrans=GWEN_DB_GetIntValue(db, "reqTrans", 0, 0);
	reqBalance=GWEN_DB_GetIntValue(db, "reqBalance", 0, 0);
	reqSto=GWEN_DB_GetIntValue(db, "reqSto", 0, 0);
	reqDT=GWEN_DB_GetIntValue(db, "reqDT", 0, 0);
	s=GWEN_DB_GetCharValue(db, "fromDate", 0, 0);
	if (s && *s) {
		GWEN_BUFFER *dbuf;
		
		dbuf=GWEN_Buffer_new(0, 32, 0, 1);
		GWEN_Buffer_AppendString(dbuf, s);
		GWEN_Buffer_AppendString(dbuf, "-12:00");
		fromTime=GWEN_Time_fromUtcString(GWEN_Buffer_GetStart(dbuf),
						 "YYYYMMDD-hh:mm");
		GWEN_Buffer_free(dbuf);
		if (fromTime==0) {
			DBG_ERROR(AQT_LOGDOMAIN, "Invalid fromdate value \"%s\"", s);
			return 1;
		}
	}
	s=GWEN_DB_GetCharValue(db, "toDate", 0, 0);
	if (s && *s) {
		GWEN_BUFFER *dbuf;
		
		dbuf=GWEN_Buffer_new(0, 32, 0, 1);
		GWEN_Buffer_AppendString(dbuf, s);
		GWEN_Buffer_AppendString(dbuf, "-12:00");
		toTime=GWEN_Time_fromUtcString(GWEN_Buffer_GetStart(dbuf),
					       "YYYYMMDD-hh:mm");
		GWEN_Buffer_free(dbuf);
		if (toTime==0) {
			DBG_ERROR(AQT_LOGDOMAIN, "Invalid todate value \"%s\"", s);
			return 1;
		}
	}

	jl=AB_Job_List2_new();

	
	al=AB_Banking_GetAccounts(ab);
	if (al) {
		AB_ACCOUNT_LIST2_ITERATOR *ait;
		
		ait=AB_Account_List2_First(al);
		if (ait) {
			AB_ACCOUNT *a;
			const char *bankId;
			const char *accountId;
			const char *bankName;
			const char *accountName;
			const char *s;

			bankId=GWEN_DB_GetCharValue(db, "bankId", 0, 0);
			bankName=GWEN_DB_GetCharValue(db, "bankName", 0, 0);
			accountId=GWEN_DB_GetCharValue(db, "accountId", 0, 0);
			accountName=GWEN_DB_GetCharValue(db, "accountName", 0, 0);
			
			a=AB_Account_List2Iterator_Data(ait);
			assert(a);
			while(a) {
				int matches=1;
				
				if (matches && bankId) {
					s=AB_Account_GetBankCode(a);
					if (!s || !*s || -1==GWEN_Text_ComparePattern(s, bankId, 0))
						matches=0;
				}
				if (matches && bankName) {
					s=AB_Account_GetBankName(a);
					if (!s || !*s || -1==GWEN_Text_ComparePattern(s, bankName, 0))
						matches=0;
				}
				
				if (matches && accountId) {
					s=AB_Account_GetAccountNumber(a);
					if (!s || !*s || -1==GWEN_Text_ComparePattern(s, accountId, 0))
						matches=0;
				}
				if (matches && accountName) {
					s=AB_Account_GetAccountName(a);
					if (!s || !*s || -1==GWEN_Text_ComparePattern(s, accountName, 0))
						matches=0;
				}

				if (matches) {
					if (reqTrans) {
						AB_JOB *j;

						j = AB_JobGetTransactions_new(a);

						AB_JobGetTransactions_SetFromTime(j, fromTime);
						AB_JobGetTransactions_SetToTime(j, toTime);

						rv = AB_Job_CheckAvailability(j, 0);
						if (rv) {
							DBG_ERROR(AQT_LOGDOMAIN,
								  "Error requesting transactions for %s/%s: %d",
								  AB_Account_GetBankCode(a),
								  AB_Account_GetAccountNumber(a),
								  rv);
							return 3;
						}
						requests++;

						AB_Job_List2_PushBack(jl, j);
					}
					if (reqBalance) {
						AB_JOB *j;

						j = AB_JobGetBalance_new(a);
						rv = AB_Job_CheckAvailability(j, 0);
						if (rv) {
							DBG_ERROR(AQT_LOGDOMAIN,
								  "Error requesting balance for %s/%s: %d",
								  AB_Account_GetBankCode(a),
								  AB_Account_GetAccountNumber(a),
								  rv);
							return 3;
						}
						requests++;

						AB_Job_List2_PushBack(jl, j);
					}
					if (reqSto) {
						AB_JOB *j;

						j = AB_JobGetStandingOrders_new(a);
						rv = AB_Job_CheckAvailability(j, 0);
						if (rv) {
							DBG_ERROR(AQT_LOGDOMAIN,
								  "Error requesting balance for %s/%s: %d",
								  AB_Account_GetBankCode(a),
								  AB_Account_GetAccountNumber(a),
								  rv);
							return 3;
						}
						requests++;

						AB_Job_List2_PushBack(jl, j);
					}

					if (reqDT) {
						AB_JOB *j;

						j = AB_JobGetDatedTransfers_new(a);
						rv = AB_Job_CheckAvailability(j, 0);
						if (rv) {
							DBG_ERROR(AQT_LOGDOMAIN,
								  "Error requesting balance for %s/%s: %d",
								  AB_Account_GetBankCode(a),
								  AB_Account_GetAccountNumber(a),
								  rv);
							return 3;
						}
						requests++;

						AB_Job_List2_PushBack(jl, j);
					}
				}
				
				a = AB_Account_List2Iterator_Next(ait);
			}

			AB_Account_List2Iterator_free(ait);
			GWEN_Time_free(toTime);
			GWEN_Time_free(fromTime);
		}
	}

	return exec_joblist(ab, db, jl);
}


int main(int argc, char **argv) 
{
	GWEN_DB_NODE *db;
	GWEN_LOGGER_LOGTYPE logType;
	GWEN_LOGGER_LEVEL logLevel;
	const char *s;
	const char *cmd;
	const char *pinFile;

	AB_BANKING *ab;
	int rv;
	int jrv;
	GWEN_GUI *gui;
	
	const GWEN_ARGS args[]={
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"cfgfile",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"C",                          /* short option */
			"cfgfile",                    /* long option */
			"Specify the configuration file",     /* short description */
			"Specify the configuration file"      /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"pinfile",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"P",                          /* short option */
			"pinfile",                    /* long option */
			"Specify the PIN file",       /* short description */
			"Specify the PIN file"        /* long description */
		},
		{
			0,                            /* flags */
			GWEN_ArgsType_Int,             /* type */
			"nonInteractive",             /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			"n",                          /* short option */
			"noninteractive",             /* long option */
			"Select non-interactive mode",/* short description */
			"Select non-interactive mode.\n"        /* long description */
			"This automatically returns a confirmative answer to any non-critical\n"
			"message."
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"charset",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"charset",                    /* long option */
			"Specify the output character set",       /* short description */
			"Specify the output character set"        /* long description */
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"logtype",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"logtype",                    /* long option */
			"Set the logtype",            /* short description */
			"Set the logtype (console, file)."
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"loglevel",                   /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"loglevel",                   /* long option */
			"Set the log level",          /* short description */
			"Set the log level (info, notice, warning, error)."
		},
		{
			GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
			GWEN_ArgsType_Char,            /* type */
			"logfile",                    /* name */
			0,                            /* minnum */
			1,                            /* maxnum */
			0,                            /* short option */
			"logfile",                   /* long option */
			"Set the log file",          /* short description */
			"Set the log file (if log type is \"file\")."
		},
		{
			GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
			GWEN_ArgsType_Int,             /* type */
			"help",                       /* name */
			0,                            /* minnum */
			0,                            /* maxnum */
			"h",                          /* short option */
			"help",                       /* long option */
			"Show this help screen",      /* short description */
			"Show this help screen"       /* long description */
		}
	};
	
	db = GWEN_DB_Group_new("arguments");
	rv = GWEN_Args_Check(argc, argv, 1,
			     GWEN_ARGS_MODE_ALLOW_FREEPARAM |
			     GWEN_ARGS_MODE_STOP_AT_FREEPARAM,
			     args,
			     db);

	if (rv==GWEN_ARGS_RESULT_ERROR) {
		fprintf(stderr, "ERROR: Could not parse arguments main\n");
		return -1;
	} else if (rv==GWEN_ARGS_RESULT_HELP) {
		GWEN_BUFFER *ubuf;

		ubuf=GWEN_Buffer_new(0, 1024, 0, 1);

		GWEN_Buffer_AppendString(ubuf, I18N("Usage: "));
		GWEN_Buffer_AppendString(ubuf, argv[0]);
		GWEN_Buffer_AppendString(ubuf, I18N(" [GLOBAL OPTIONS] "
						    "COMMAND "
						    "[LOCAL OPTIONS]\n"));
		
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, I18N("Global Options\n"));
		GWEN_Buffer_AppendString(ubuf, I18N("==============\n\n"));
		GWEN_Buffer_AppendString(ubuf, I18N("Global options preceed a command.\n"));
		GWEN_Buffer_AppendString(ubuf,
					 I18N("Every command has the local option "
					      "\"-h\".\n"
					      "Please use that option on the commands"
					      "you are interested in.\n"));
		if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
			fprintf(stderr, "ERROR: Could not create help string\n");
			return 1;
		}
		GWEN_Buffer_AppendString(ubuf, "\n\n");
		GWEN_Buffer_AppendString(ubuf, I18N("Commands\n"));
		GWEN_Buffer_AppendString(ubuf, I18N("========\n\n"));
		GWEN_Buffer_AppendString(ubuf, " listaccs\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Prints a list of accounts\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " request\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Executes a request for transactions, "
					      " balances, standing orders\n"
					      "  etc.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " transfer\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Executes a transfer request.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " debitnote\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Executes a debit note request.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " listtrans\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Exports results from the queue's "
					      "execution.\n"
					      "  This command specifically exports "
					      "transactions.\n"));
		
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " listbal\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Exports results from the queue's "
					      "execution.\n"
					      "  This command specifically exports "
					      "balances.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " chkacc\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Check a combination of bank id and "
					      "account number\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " chkiban\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Check an IBAN, an international bank "
					      "account number\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " import\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Import a file.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n");
		GWEN_Buffer_AppendString(ubuf, " joblog\n");
		GWEN_Buffer_AppendString(ubuf,
					 I18N("  Show the log of a job.\n"));
		GWEN_Buffer_AppendString(ubuf, "\n\n");
		GWEN_Buffer_AppendString(ubuf, I18N("Example\n"));
		GWEN_Buffer_AppendString(ubuf, I18N("=======\n\n"));
		GWEN_Buffer_AppendString(ubuf, argv[0]);
		GWEN_Buffer_AppendString(ubuf,
					 I18N(" listtrans -h\n"
					      "This example prints the help screen "
					      "for the command \"listtrans\"\n"));
		
		fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
		GWEN_Buffer_free(ubuf);
		return 0;
	}

	if (rv) {
		argc-=rv-1;
		argv+=rv-1;
	}

	/* setup logging */
	s = GWEN_DB_GetCharValue(db, "loglevel", 0, "warning");
	logLevel = GWEN_Logger_Name2Level(s);
	if (logLevel == GWEN_LoggerLevel_Unknown) {
		fprintf(stderr, "ERROR: Unknown log level (%s)\n", s);
		return 1;
	}
	s = GWEN_DB_GetCharValue(db, "logtype", 0, "console");
	logType = GWEN_Logger_Name2Logtype(s);
	if (logType == GWEN_LoggerType_Unknown) {
		fprintf(stderr, "ERROR: Unknown log type (%s)\n", s);
		return 1;
	}
	rv = GWEN_Logger_Open(AQBANKING_LOGDOMAIN,
			      "aqbanking3-tool",
			      GWEN_DB_GetCharValue(db, "logfile", 0,
						   "aqbanking3-tool.log"),
			      logType,
			      GWEN_LoggerFacility_User);
	if (rv) {
		fprintf(stderr, "ERROR: Could not setup logging (%d).\n", rv);
		return 2;
	}
	GWEN_Logger_SetLevel(AQT_LOGDOMAIN, logLevel);


	cmd=GWEN_DB_GetCharValue(db, "params", 0, 0);
	if (!cmd) {
		fprintf(stderr, "ERROR: Command needed.\n");
		return 1;
	}

	gui = GWEN_Gui_CGui_new();
	GWEN_Gui_SetGui(gui);

	GWEN_Gui_CGui_SetIsNonInteractive(
		gui, GWEN_DB_GetIntValue(db, "nonInteractive", 0, 0));


	pinFile=GWEN_DB_GetCharValue(db, "pinFile", 0, 0);
	if (pinFile) {
		GWEN_DB_NODE *dbPins;

		dbPins=GWEN_DB_Group_new("pins");
		if (GWEN_DB_ReadFile(dbPins, pinFile,
				     GWEN_DB_FLAGS_DEFAULT |
				     GWEN_PATH_FLAGS_CREATE_GROUP, 0, 2000)) {
			DBG_ERROR(AQT_LOGDOMAIN, "Error reading pinfile \"%s\"", pinFile);
			return 2;
		}
		GWEN_Gui_CGui_SetPasswordDb(gui, dbPins, 1);
	}

	ab = AB_Banking_new("aqbanking3-tool", 0, 0);

	rv = AB_Banking_Init(ab);
	if (rv) {
		fprintf(stderr, "Error on init (%d)\n", rv);
		return 2;
	}
	fprintf(stderr, "AqBanking successfully initialized.\n");

#if ( AQBANKING_SO_EFFECTIVE >= 28 )
	rv = AB_Banking_OnlineInit(ab, 0);
#else
	rv = AB_Banking_OnlineInit(ab);
#endif
	if (rv) {
		fprintf(stderr, "Error on init of online modules (%d)\n", rv);
		return 2;
	}

#if 0
	/* TODO */
	if (strcasecmp(cmd, "listaccs")==0) {
		jrv=listAccs(ab, db, argc, argv);
	}
	else 
#endif
	if (strcasecmp(cmd, "request")==0) {
		jrv=request(ab, db, argc, argv);
	}
#if 0
	/* TODO */
	else if (strcasecmp(cmd, "listtrans")==0) {
		jrv=listTrans(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "transfer")==0) {
		jrv=transfer(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "debitnote")==0) {
		jrv=debitNote(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "chkacc")==0) {
		jrv=chkAcc(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "chkiban")==0) {
		jrv=chkIban(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "listbal")==0) {
		jrv=listBal(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "import")==0) {
		jrv=import(ab, db, argc, argv);
	}
	else if (strcasecmp(cmd, "joblog")==0) {
		jrv=jobLog(ab, db, argc, argv);
	}
#endif
	else {
		fprintf(stderr, "ERROR: Unknown command \"%s\".\n", cmd);
		fprintf(stderr, "NOTICE: only request is currently implemented!\n");
		jrv=1;
	}

	/* This function MUST be called in order to let AqBanking save the changes
	 * to the users and accounts (like they occur after executing jobs).
	 */
#if ( AQBANKING_SO_EFFECTIVE >= 28 )
	rv = AB_Banking_OnlineFini(ab,0);
#else
	rv = AB_Banking_OnlineFini(ab);
#endif
	if (rv) {
		fprintf(stderr, "ERROR: Error on deinit online modules (%d)\n", rv);
		return 3;
	}

	/* This function deinitializes AqBanking. It undoes the effects of
	 * AB_Banking_Init() and should be called before destroying an AB_BANKING
	 * object.
	 */
	rv = AB_Banking_Fini(ab);
	if (rv) {
		fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv);
		return 3;
	}
	AB_Banking_free(ab);
	
	return jrv;
}




