/*-------------------------------------------------------------------------
 * drawElements Utility Library
 * ----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Command line parser.
 *//*--------------------------------------------------------------------*/

#include "deCommandLine.h"
#include "deMemPool.h"
#include "dePoolArray.h"
#include "deMemory.h"
#include "deString.h"

#include <string.h>

DE_DECLARE_POOL_ARRAY(CharPtrArray, char*);

enum
{
	MAX_ARGS = 64
};

deCommandLine* deCommandLine_parse (const char* commandLine)
{
	deMemPool*		tmpPool		= deMemPool_createRoot(DE_NULL, 0);
	CharPtrArray*	args		= tmpPool ? CharPtrArray_create(tmpPool) : DE_NULL;
	char*			buf			= DE_NULL;
	char*			outPtr;
	int				pos;
	int				argNdx;
	char			strChr;

	if (!args)
	{
		if (tmpPool)
			deMemPool_destroy(tmpPool);
		return DE_NULL;
	}

	DE_ASSERT(commandLine);

	/* Create buffer for args (no expansion can happen). */
	buf		= (char*)deCalloc(strlen(commandLine)+1);
	pos		= 0;
	argNdx	= 0;
	outPtr	= buf;
	strChr	= 0;

	if (!buf || !CharPtrArray_pushBack(args, buf))
	{
		deMemPool_destroy(tmpPool);
		return DE_NULL;
	}

	while (commandLine[pos] != 0)
	{
		char c = commandLine[pos++];

		if (strChr != 0 && c == '\\')
		{
			/* Escape. */
			c = commandLine[pos++];
			switch (c)
			{
				case 'n':	*outPtr++ = '\n';	break;
				case 't':	*outPtr++ = '\t';	break;
				default:	*outPtr++ = c;		break;
			}
		}
		else if (strChr != 0 && c == strChr)
		{
			/* String end. */
			strChr = 0;
		}
		else if (strChr == 0 && (c == '"' || c == '\''))
		{
			/* String start. */
			strChr = c;
		}
		else if (c == ' ' && strChr == 0)
		{
			/* Arg end. */
			*outPtr++		 = 0;
			argNdx			+= 1;
			if (!CharPtrArray_pushBack(args, outPtr))
			{
				deFree(buf);
				deMemPool_destroy(tmpPool);
				return DE_NULL;
			}
		}
		else
			*outPtr++ = c;
	}

	DE_ASSERT(commandLine[pos] == 0);

	/* Terminate last arg. */
	*outPtr = 0;

	/* Create deCommandLine. */
	{
		deCommandLine* cmdLine = (deCommandLine*)deCalloc(sizeof(deCommandLine));

		if (!cmdLine || !(cmdLine->args = (char**)deCalloc(sizeof(char*)*(size_t)CharPtrArray_getNumElements(args))))
		{
			deFree(cmdLine);
			deFree(buf);
			deMemPool_destroy(tmpPool);
			return DE_NULL;
		}

		cmdLine->numArgs	= CharPtrArray_getNumElements(args);
		cmdLine->argBuf		= buf;

		for (argNdx = 0; argNdx < cmdLine->numArgs; argNdx++)
			cmdLine->args[argNdx] = CharPtrArray_get(args, argNdx);

		deMemPool_destroy(tmpPool);
		return cmdLine;
	}
}

void deCommandLine_destroy (deCommandLine* cmdLine)
{
	deFree(cmdLine->argBuf);
	deFree(cmdLine);
}

static void testParse (const char* cmdLine, const char* const* refArgs, int numArgs)
{
	deCommandLine*	parsedCmdLine	= deCommandLine_parse(cmdLine);
	int				argNdx;

	DE_TEST_ASSERT(parsedCmdLine);
	DE_TEST_ASSERT(parsedCmdLine->numArgs == numArgs);

	for (argNdx = 0; argNdx < numArgs; argNdx++)
		DE_TEST_ASSERT(deStringEqual(parsedCmdLine->args[argNdx], refArgs[argNdx]));

	deCommandLine_destroy(parsedCmdLine);
}

void deCommandLine_selfTest (void)
{
	{
		const char* cmdLine	= "hello";
		const char* ref[]	= { "hello" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello world";
		const char* ref[]	= { "hello", "world" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello/world";
		const char* ref[]	= { "hello/world" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello/world --help";
		const char* ref[]	= { "hello/world", "--help" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello/world --help foo";
		const char* ref[]	= { "hello/world", "--help", "foo" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello\\world --help foo";
		const char* ref[]	= { "hello\\world", "--help", "foo" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "\"hello/worl d\" --help --foo=\"bar\" \"ba z\\\"\"";
		const char* ref[]	= { "hello/worl d", "--help", "--foo=bar", "ba z\"" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "'hello/worl d' --help --foo='bar' 'ba z\\\''";
		const char* ref[]	= { "hello/worl d", "--help", "--foo=bar", "ba z'" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello \"'world'\"";
		const char* ref[]	= { "hello", "'world'" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello '\"world\"'";
		const char* ref[]	= { "hello", "\"world\"" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
	{
		const char* cmdLine	= "hello \"world\\n\"";
		const char* ref[]	= { "hello", "world\n" };
		testParse(cmdLine, ref, DE_LENGTH_OF_ARRAY(ref));
	}
}
