/*-------------------------------------------------------------------------
 *
 * dict.c
 *		Standard interface to dictionary
 *
 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
 *
 *
 * IDENTIFICATION
 *	  src/backend/tsearch/dict.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "catalog/pg_type.h"
#include "tsearch/ts_cache.h"
#include "tsearch/ts_public.h"
#include "utils/array.h"
#include "utils/builtins.h"


/*
 * Lexize one word by dictionary, mostly debug function
 */
Datum
ts_lexize(PG_FUNCTION_ARGS)
{
	Oid			dictId = PG_GETARG_OID(0);
	text	   *in = PG_GETARG_TEXT_PP(1);
	ArrayType  *a;
	TSDictionaryCacheEntry *dict;
	TSLexeme   *res,
			   *ptr;
	Datum	   *da;
	DictSubState dstate = {false, false, NULL};

	dict = lookup_ts_dictionary_cache(dictId);

	res = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
													 PointerGetDatum(dict->dictData),
													 PointerGetDatum(VARDATA_ANY(in)),
													 Int32GetDatum(VARSIZE_ANY_EXHDR(in)),
													 PointerGetDatum(&dstate)));

	if (dstate.getnext)
	{
		dstate.isend = true;
		ptr = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
														 PointerGetDatum(dict->dictData),
														 PointerGetDatum(VARDATA_ANY(in)),
														 Int32GetDatum(VARSIZE_ANY_EXHDR(in)),
														 PointerGetDatum(&dstate)));
		if (ptr != NULL)
			res = ptr;
	}

	if (!res)
		PG_RETURN_NULL();

	ptr = res;
	while (ptr->lexeme)
		ptr++;
	da = (Datum *) palloc(sizeof(Datum) * (ptr - res));
	ptr = res;
	while (ptr->lexeme)
	{
		da[ptr - res] = CStringGetTextDatum(ptr->lexeme);
		ptr++;
	}

	a = construct_array_builtin(da, ptr - res, TEXTOID);

	ptr = res;
	while (ptr->lexeme)
	{
		pfree(DatumGetPointer(da[ptr - res]));
		pfree(ptr->lexeme);
		ptr++;
	}
	pfree(res);
	pfree(da);

	PG_RETURN_POINTER(a);
}
