/*
  This code implements one part of functonality of
  free available library PL/Vision. Please look www.quest.com

  Original author: Steven Feuerstein, 1996 - 2002
  PostgreSQL implementation author: Pavel Stehule, 2006

  This module is under BSD Licence

  History:
    1.0. first public version 13. March 2006
*/

#include "postgres.h"
#include "utils/date.h"
#include "utils/builtins.h"
#include "utils/nabstime.h"
#include <sys/time.h>
#include <stdlib.h>
#include "lib/stringinfo.h"

#include "plvlex.h"
#include "nodes/pg_list.h"
#include "funcapi.h"
#include "catalog/pg_type.h"
#include "orafunc.h"
#include "builtins.h"

#define YYPARSE_PARAM
#include "sqlparse.h"

typedef struct {
	List	*nodes;
	int 	nnodes;
	int	cnode;
	char **values;
} tokensFctx;

PG_FUNCTION_INFO_V1(plvlex_tokens);

extern int      orafce_sql_yyparse(void *);
extern void orafce_sql_yyerror(const char *message);
extern void orafce_sql_scanner_init(const char *str);
extern void orafce_sql_scanner_finish(void);

static orafce_lexnode *__node;

static char *__result;
static int __len;

#define CSTRING(txt) \
	( \
    __len = VARSIZE(txt) - VARHDRSZ, \
    __result = palloc(__len + 1), \
    memcpy(__result, VARDATA(txt), __len), \
    __result[__len] = '\0', \
    __result)


#define COPY_TO_S(src,dest,col)	(dest->col = (src->col ? pstrdup(src->col) : NULL))
#define COPY_TO(src,dest,col)	(dest->col = src->col)

#define COPY_FIELDS(src,dest) \
	COPY_TO(src, dest, typenode), \
	COPY_TO_S(src,dest,str), \
	COPY_TO(src,dest,keycode), \
	COPY_TO(src,dest,lloc), \
	COPY_TO_S(src,dest,sep), \
	COPY_TO(src,dest,modificator), \
	COPY_TO(src,dest,classname)


#define COPY_NODE(src)   \
  ( \
    __node = (orafce_lexnode*) palloc(sizeof(orafce_lexnode)),  \
    COPY_FIELDS(src,__node), \
    __node)


/* Finding triplet a.b --> a */

#define IsType(node, type)	(node->typenode == X_##type)
#define APPEND_NODE(list,nd)	\
	if (nd) \
	{ \
		list = lappend(list, nd); \
		nd = NULL; \
	}

#define mod(a)  (a->modificator)
#define SF(a)	(a ? a : "")

#define NEWNODE(type) \
	( \
	__node = (orafce_lexnode *) palloc(sizeof(orafce_lexnode)), \
	__node->typenode = X_##type, \
	__node->modificator = NULL, \
	__node->sep = NULL, \
	__node->keycode = -1, \
	__node->classname = #type, \
	__node->lloc = 0, \
	__node )



static orafce_lexnode *
compose(orafce_lexnode *a, orafce_lexnode *b)
{
	orafce_lexnode *result;
	StringInfo sinfo;

	sinfo = makeStringInfo();
	result = NEWNODE(IDENT);
	result->lloc = a->lloc;

	if (strcmp(SF(mod(a)), "dq") == 0)
		appendStringInfo(sinfo, "\"%s\".", a->str);
	else
	{
		appendStringInfoString(sinfo, a->str);
		appendStringInfoChar(sinfo, '.');
	}

	if (strcmp(SF(mod(b)), "dq") == 0)
		appendStringInfo(sinfo, "\"%s\"", b->str);
	else
		appendStringInfoString(sinfo, b->str);

	result->str = sinfo->data;

	return result;
}

static List *
filterList(List *list, bool skip_spaces, bool qnames)
{
	List *result = NIL;
	ListCell *cell;
	bool isdot = false;
	orafce_lexnode *a = NULL;
	orafce_lexnode *dot = NULL;

	foreach(cell, list)
	{
		orafce_lexnode *nd = (orafce_lexnode *) lfirst(cell);

		if (qnames)
		{
			isdot = (IsType(nd, OTHERS) && (nd->str[0] == '.'));

			if (IsType(nd, IDENT) && dot && a)
			{
				a = compose(a, nd);
				dot = NULL;
				continue;
			}
			else if (isdot && !dot && a)
			{
				dot = COPY_NODE(nd);
				continue;
			}
			else if (IsType(nd, IDENT) && !a)
			{
				a = COPY_NODE(nd);
				continue;
			}
		}

		/* clean buffered values */
		APPEND_NODE(result,a);
		APPEND_NODE(result,dot);

		if (!(skip_spaces && IsType(nd, WHITESPACE)))
		{
			result = lappend(result, COPY_NODE(nd));
		}
	}

	/* clean buffered values */
	APPEND_NODE(result,a);
	APPEND_NODE(result,dot);

	return result;
}

Datum plvlex_tokens(PG_FUNCTION_ARGS)
{
	FuncCallContext	   *funcctx;
	TupleDesc			tupdesc;
	TupleTableSlot	   *slot;
	AttInMetadata	   *attinmeta;
	tokensFctx		   *fctx;


	if (SRF_IS_FIRSTCALL ())
	{
		MemoryContext  oldcontext;
		List *lexems;
		text *src = PG_GETARG_TEXT_P(0);
		bool skip_spaces = PG_GETARG_BOOL(1);
		bool qnames = PG_GETARG_BOOL(2);

		orafce_sql_scanner_init(CSTRING(src));
		if (orafce_sql_yyparse(&lexems) != 0)
			orafce_sql_yyerror("bogus input");

		orafce_sql_scanner_finish();

		funcctx = SRF_FIRSTCALL_INIT ();
		oldcontext = MemoryContextSwitchTo (funcctx->multi_call_memory_ctx);

		fctx = (tokensFctx*) palloc (sizeof (tokensFctx));
		funcctx->user_fctx = (void *)fctx;

		fctx->nodes = filterList(lexems, skip_spaces, qnames);
		fctx->nnodes = list_length(fctx->nodes);
		fctx->cnode = 0;

		fctx->values = (char **) palloc (6 * sizeof (char *));
		fctx->values  [0] = (char*) palloc (16 * sizeof (char));
		fctx->values  [1] = (char*) palloc (1024 * sizeof (char));
		fctx->values  [2] = (char*) palloc (16 * sizeof (char));
		fctx->values  [3] = (char*) palloc (16 * sizeof (char));
		fctx->values  [4] = (char*) palloc (255 * sizeof (char));
		fctx->values  [5] = (char*) palloc (255 * sizeof (char));

		tupdesc = CreateTemplateTupleDesc (6 , false);

		TupleDescInitEntry (tupdesc,  1, "start_pos", INT4OID, -1, 0);
		TupleDescInitEntry (tupdesc,  2, "token",     TEXTOID, -1, 0);
		TupleDescInitEntry (tupdesc,  3, "keycode",   INT4OID, -1, 0);
		TupleDescInitEntry (tupdesc,  4, "class",     TEXTOID, -1, 0);
		TupleDescInitEntry (tupdesc,  5, "separator", TEXTOID, -1, 0);
		TupleDescInitEntry (tupdesc,  6, "mod",       TEXTOID, -1, 0);

		slot = TupleDescGetSlot (tupdesc);
		funcctx -> slot = slot;

		attinmeta = TupleDescGetAttInMetadata (tupdesc);
		funcctx -> attinmeta = attinmeta;

		MemoryContextSwitchTo (oldcontext);
	}


	funcctx = SRF_PERCALL_SETUP ();
	fctx = (tokensFctx*) funcctx->user_fctx;

	while (fctx->cnode < fctx->nnodes)
	{
		char **values;
		Datum result;
		HeapTuple tuple;
		char *back_vals[6];

		orafce_lexnode *nd = (orafce_lexnode*) list_nth(fctx->nodes, fctx->cnode++);
		values = fctx->values;

		back_vals[2] = values[2];
		back_vals[4] = values[4];
		back_vals[5] = values[5];

		snprintf(values[0],    16, "%d", nd->lloc);
		snprintf(values[1], 10000, "%s", SF(nd->str));
		snprintf(values[2],    16, "%d", nd->keycode);
		snprintf(values[3],    16, "%s", nd->classname);
		snprintf(values[4],   255, "%s", SF(nd->sep));
		snprintf(values[5],    48, "%s", SF(nd->modificator));

		if (nd->keycode == -1)
			values[2] = NULL;

		if (!nd->sep)
			values[4] = NULL;

		if (!nd->modificator)
			values[5] = NULL;

		tuple = BuildTupleFromCStrings (funcctx -> attinmeta,
							fctx -> values);
		result = TupleGetDatum (funcctx -> slot, tuple);

		values[2] = back_vals[2];
		values[4] = back_vals[4];
		values[5] = back_vals[5];

		SRF_RETURN_NEXT (funcctx, result);
	}

	SRF_RETURN_DONE (funcctx);
}

