/****************************************************************
 *								*
 * Copyright (c) 2001-2016 Fidelity National Information	*
 * Services, Inc. and/or its subsidiaries. All rights reserved.	*
 *								*
 *	This source code contains the intellectual property	*
 *	of its copyright holder(s), and is made available	*
 *	under a license.  If you do not know the terms of	*
 *	the license, please stop and do not read further.	*
 *								*
 ****************************************************************/

#include "mdef.h"

#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "format_targ_key.h"
#include "gvsub2str.h"

/* return a pointer that points after the last char added */
unsigned char *format_targ_key(unsigned char *out_char_ptr, int4 max_size, gv_key *key, boolean_t dollarc)
{
	unsigned char			ch, *gvkey_char_ptr, *out_top, *work_char_ptr, work_buff[MAX_ZWR_KEY_SZ], *work_top;
	boolean_t			is_string;
	mstr				opstr;
	unsigned char			*gvkey_top_ptr;

	assert(12 < max_size);
	out_top = out_char_ptr + max_size - 2;	/* - 2, as could add comma left-paren or TWO double quotes between checks */
	gvkey_char_ptr = key->base;
	gvkey_top_ptr = gvkey_char_ptr + key->end;
	/* Ensure input key is well-formed (i.e. double null terminated) */
	assert(KEY_DELIMITER == *(gvkey_top_ptr - 1));
	assert(KEY_DELIMITER == *gvkey_top_ptr);
	for (*out_char_ptr++ = '^'; (*out_char_ptr = *gvkey_char_ptr++) && (gvkey_char_ptr <= gvkey_top_ptr); out_char_ptr++)
		;
	/* The following asserts (in the for loop) assume that a global name will be able to fit in completely into any key. */
	assert(gvkey_char_ptr <= gvkey_top_ptr);
	if (0 == *gvkey_char_ptr)		/* no subscipts */
		return (out_char_ptr);
	*out_char_ptr++ = '(';
	for ( ; gvkey_char_ptr <= gvkey_top_ptr; )
	{
		assert(gvkey_char_ptr <= gvkey_top_ptr);
		if (0x01 == *gvkey_char_ptr)	/* this must be a null string which was adjusted by op_gvorder */
		{
			*out_char_ptr++ = '"';
			*out_char_ptr++ = '"';
		} else
		{
			is_string = FALSE;
			if ((STR_SUB_PREFIX == *gvkey_char_ptr) && !dollarc)
			{
				is_string = TRUE;
				*out_char_ptr++ = '"';
			}
			opstr.addr = (char *)work_buff;
			opstr.len = MAX_ZWR_KEY_SZ;
			work_top = gvsub2str(gvkey_char_ptr, &opstr, dollarc);
			if (!is_string)
			{
				for (work_char_ptr = work_buff;  work_char_ptr < work_top;)
				{
					if (out_char_ptr >= out_top)
					{
						assert(FALSE);
						return (NULL);
					}
					*out_char_ptr++ = *work_char_ptr++;
				}
			} else
			{	/* replace double-quote with TWO double-quotes since this subs is already double-quote-enclosed */
				for (work_char_ptr = work_buff;  work_char_ptr < work_top;)
				{
					if (out_char_ptr >= out_top)
					{
						assert(FALSE);
						return (NULL);
					}
					*out_char_ptr++ = (ch = *work_char_ptr++);
					if ('"' == ch)
					{
						if (out_char_ptr >= out_top)
						{
							assert(FALSE);
							return (NULL);
						}
						*out_char_ptr++ = ch;
					}
				}
				if (out_char_ptr >= out_top)
				{
					assert(FALSE);
					return (NULL);
				}
				*out_char_ptr++ = '"';
			}
		}
		if (out_char_ptr >= out_top)
		{
			assert(FALSE);
			return (NULL);
		}
		/* Advance until next null separator */
		for ( ; *gvkey_char_ptr++ && (gvkey_char_ptr <= gvkey_top_ptr); )
			;
		if (gvkey_char_ptr > gvkey_top_ptr)
		{
			assert(FALSE);
			return (NULL);
		}
		if (*gvkey_char_ptr)
			*out_char_ptr++ = ',';
		else
			break;
	}
	if((out_char_ptr >= out_top) || (gvkey_char_ptr > gvkey_top_ptr))
	{
		assert(FALSE);
		return (NULL);
	}
	*out_char_ptr++ = ')';
	return (out_char_ptr);
}
