/*-------------------------------------------------------------------------
 * drawElements C++ Base 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.hpp"

#include <set>
#include <sstream>
#include <cstring>
#include <stdexcept>
#include <algorithm>

namespace de
{
namespace cmdline
{

namespace
{
struct Help { typedef bool ValueType; };
}

namespace detail
{

inline const char* getNamedValueName (const void* namedValue)
{
	return static_cast<const NamedValue<deUint8>*>(namedValue)->name;
}

using std::set;

TypedFieldMap::TypedFieldMap (void)
{
}

TypedFieldMap::~TypedFieldMap (void)
{
	clear();
}

void TypedFieldMap::clear (void)
{
	for (Map::const_iterator iter = m_fields.begin(); iter != m_fields.end(); ++iter)
	{
		if (iter->second.value)
			iter->second.destructor(iter->second.value);
	}
	m_fields.clear();
}

bool TypedFieldMap::contains (const std::type_info* key) const
{
	return m_fields.find(key) != m_fields.end();
}

const TypedFieldMap::Entry& TypedFieldMap::get (const std::type_info* key) const
{
	Map::const_iterator pos = m_fields.find(key);
	if (pos != m_fields.end())
		return pos->second;
	else
		throw std::out_of_range("Value not set");
}

void TypedFieldMap::set (const std::type_info* key, const Entry& value)
{
	Map::iterator pos = m_fields.find(key);

	if (pos != m_fields.end())
	{
		pos->second.destructor(pos->second.value);
		pos->second.value = DE_NULL;

		pos->second = value;
	}
	else
		m_fields.insert(std::make_pair(key, value));
}

Parser::Parser (void)
{
	addOption(Option<Help>("h", "help", "Show this help"));
}

Parser::~Parser (void)
{
}

void Parser::addOption (const OptInfo& option)
{
	m_options.push_back(option);
}

bool Parser::parse (int numArgs, const char* const* args, CommandLine* dst, std::ostream& err) const
{
	typedef map<string, const OptInfo*> OptMap;
	typedef set<const OptInfo*> OptSet;

	OptMap	shortOptMap;
	OptMap	longOptMap;
	OptSet	seenOpts;
	bool	allOk			= true;

	DE_ASSERT(dst->m_args.empty() && dst->m_options.empty());

	for (vector<OptInfo>::const_iterator optIter = m_options.begin(); optIter != m_options.end(); optIter++)
	{
		const OptInfo& opt = *optIter;

		DE_ASSERT(opt.shortName || opt.longName);

		if (opt.shortName)
		{
			DE_ASSERT(shortOptMap.find(opt.shortName) == shortOptMap.end());
			shortOptMap[opt.shortName] = &opt;
		}

		if (opt.longName)
		{
			DE_ASSERT(longOptMap.find(opt.longName) == longOptMap.end());
			longOptMap[opt.longName] = &opt;
		}

		// Set default values.
		if (opt.defaultValue)
			opt.dispatchParse(&opt, opt.defaultValue, &dst->m_options);
		else if (opt.setDefault)
			opt.setDefault(&dst->m_options);
	}

	DE_ASSERT(!dst->m_options.get<Help>());

	for (int argNdx = 0; argNdx < numArgs; argNdx++)
	{
		const char*		arg		= args[argNdx];
		int				argLen	= (int)strlen(arg);

		if (arg[0] == '-' && arg[1] == '-' && arg[2] == 0)
		{
			// End of option list (--)
			for (int optNdx = argNdx+1; optNdx < numArgs; optNdx++)
				dst->m_args.push_back(args[optNdx]);
			break;
		}
		else if (arg[0] == '-')
		{
			const bool				isLongName	= arg[1] == '-';
			const char*				nameStart	= arg + (isLongName ? 2 : 1);
			const char*				nameEnd		= std::find(nameStart, arg+argLen, '=');
			const bool				hasImmValue	= nameEnd != (arg+argLen);
			const OptMap&			optMap		= isLongName ? longOptMap : shortOptMap;
			OptMap::const_iterator	optPos		= optMap.find(string(nameStart, nameEnd));
			const OptInfo*			opt			= optPos != optMap.end() ? optPos->second : DE_NULL;

			if (!opt)
			{
				err << "Unrecognized command line option '" << arg << "'\n";
				allOk = false;
				continue;
			}

			if (seenOpts.find(opt) != seenOpts.end())
			{
				err << "Command line option '--" << opt->longName << "' specified multiple times\n";
				allOk = false;
				continue;
			}

			seenOpts.insert(opt);

			if (opt->isFlag)
			{
				if (!hasImmValue)
				{
					opt->dispatchParse(opt, DE_NULL, &dst->m_options);
				}
				else
				{
					err << "No value expected for command line option '--" << opt->longName << "'\n";
					allOk = false;
				}
			}
			else
			{
				const bool	hasValue	= hasImmValue || (argNdx+1 < numArgs);

				if (hasValue)
				{
					const char*	value	= hasValue ? (hasImmValue ? nameEnd+1 : args[argNdx+1]) : DE_NULL;

					if (!hasImmValue)
						argNdx += 1; // Skip value

					try
					{
						opt->dispatchParse(opt, value, &dst->m_options);
					}
					catch (const std::exception& e)
					{
						err << "Got error parsing command line option '--" << opt->longName << "': " << e.what() << "\n";
						allOk = false;
					}
				}
				else
				{
					err << "Expected value for command line option '--" << opt->longName << "'\n";
					allOk = false;
				}
			}
		}
		else
		{
			// Not an option
			dst->m_args.push_back(arg);
		}
	}

	// Help specified?
	if (dst->m_options.get<Help>())
		allOk = false;

	return allOk;
}

void Parser::help (std::ostream& str) const
{
	for (vector<OptInfo>::const_iterator optIter = m_options.begin(); optIter != m_options.end(); ++optIter)
	{
		const OptInfo& opt = *optIter;

		str << "  ";
		if (opt.shortName)
			str << "-" << opt.shortName;

		if (opt.shortName && opt.longName)
			str << ", ";

		if (opt.longName)
			str << "--" << opt.longName;

		if (opt.namedValues)
		{
			str << "=[";

			for (const void* curValue = opt.namedValues; curValue != opt.namedValuesEnd; curValue = (const void*)((deUintptr)curValue + opt.namedValueStride))
			{
				if (curValue != opt.namedValues)
					str << "|";
				str << getNamedValueName(curValue);
			}

			str << "]";
		}
		else if (!opt.isFlag)
			str << "=<value>";

		str << "\n";

		if (opt.description)
			str << "    " << opt.description << "\n";

		if (opt.defaultValue)
			str << "    default: '" << opt.defaultValue << "'\n";

		str << "\n";
	}
}

void CommandLine::clear (void)
{
	m_options.clear();
	m_args.clear();
}

const void* findNamedValueMatch (const char* src, const void* namedValues, const void* namedValuesEnd, size_t stride)
{
	std::string srcStr(src);

	for (const void* curValue = namedValues; curValue != namedValuesEnd; curValue = (const void*)((deUintptr)curValue + stride))
	{
		if (srcStr == getNamedValueName(curValue))
			return curValue;
	}

	throw std::invalid_argument("unrecognized value '" + srcStr + "'");
}

} // detail

// Default / parsing functions

template<>
void getTypeDefault (bool* dst)
{
	*dst = false;
}

template<>
void parseType<bool> (const char*, bool* dst)
{
	*dst = true;
}

template<>
void parseType<std::string> (const char* src, std::string* dst)
{
	*dst = src;
}

template<>
void parseType<int> (const char* src, int* dst)
{
	std::istringstream str(src);
	str >> *dst;
	if (str.bad() || !str.eof())
		throw std::invalid_argument("invalid integer literal");
}

// Tests

DE_DECLARE_COMMAND_LINE_OPT(TestStringOpt,		std::string);
DE_DECLARE_COMMAND_LINE_OPT(TestStringDefOpt,	std::string);
DE_DECLARE_COMMAND_LINE_OPT(TestIntOpt,			int);
DE_DECLARE_COMMAND_LINE_OPT(TestBoolOpt,		bool);
DE_DECLARE_COMMAND_LINE_OPT(TestNamedOpt,		deUint64);

void selfTest (void)
{
	// Parsing with no options.
	{
		Parser parser;

		{
			std::ostringstream	err;
			CommandLine			cmdLine;
			const bool			parseOk		= parser.parse(0, DE_NULL, &cmdLine, err);

			DE_TEST_ASSERT(parseOk && err.str().empty());
		}

		{
			const char*			args[]		= { "-h" };
			std::ostringstream	err;
			CommandLine			cmdLine;
			const bool			parseOk		= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(err.str().empty()); // No message about -h
		}

		{
			const char*			args[]		= { "--help" };
			std::ostringstream	err;
			CommandLine			cmdLine;
			const bool			parseOk		= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(err.str().empty()); // No message about -h
		}

		{
			const char*			args[]		= { "foo", "bar", "baz baz" };
			std::ostringstream	err;
			CommandLine			cmdLine;
			const bool			parseOk		= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(parseOk && err.str().empty());
			DE_TEST_ASSERT(cmdLine.getArgs().size() == DE_LENGTH_OF_ARRAY(args));

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(args); ndx++)
				DE_TEST_ASSERT(cmdLine.getArgs()[ndx] == args[ndx]);
		}
	}

	// Parsing with options.
	{
		Parser parser;

		static const NamedValue<deUint64> s_namedValues[] =
		{
			{ "zero",	0		},
			{ "one",	1		},
			{ "huge",	~0ull	}
		};

		parser << Option<TestStringOpt>		("s",	"string",	"String option")
			   << Option<TestStringDefOpt>	("x",	"xyz",		"String option w/ default value",	"foo")
			   << Option<TestIntOpt>		("i",	"int",		"Int option")
			   << Option<TestBoolOpt>		("b",	"bool",		"Test boolean flag")
			   << Option<TestNamedOpt>		("n",	"named",	"Test named opt",	DE_ARRAY_BEGIN(s_namedValues),	DE_ARRAY_END(s_namedValues),	"one");

		{
			std::ostringstream err;
			DE_TEST_ASSERT(err.str().empty());
			parser.help(err);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Default values
		{
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(0, DE_NULL, &cmdLine, err);

			DE_TEST_ASSERT(parseOk);
			DE_TEST_ASSERT(err.str().empty());

			DE_TEST_ASSERT(!cmdLine.hasOption<TestStringOpt>());
			DE_TEST_ASSERT(!cmdLine.hasOption<TestIntOpt>());
			DE_TEST_ASSERT(cmdLine.getOption<TestNamedOpt>() == 1);
			DE_TEST_ASSERT(cmdLine.getOption<TestBoolOpt>() == false);
			DE_TEST_ASSERT(cmdLine.getOption<TestStringDefOpt>() == "foo");
		}

		// Basic parsing
		{
			const char*			args[]	= { "-s", "test value", "-b", "-i=9", "--named=huge" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(parseOk);
			DE_TEST_ASSERT(err.str().empty());

			DE_TEST_ASSERT(cmdLine.getOption<TestStringOpt>() == "test value");
			DE_TEST_ASSERT(cmdLine.getOption<TestIntOpt>() == 9);
			DE_TEST_ASSERT(cmdLine.getOption<TestBoolOpt>());
			DE_TEST_ASSERT(cmdLine.getOption<TestNamedOpt>() == ~0ull);
			DE_TEST_ASSERT(cmdLine.getOption<TestStringDefOpt>() == "foo");
		}

		// End of argument list (--)
		{
			const char*			args[]	= { "--string=foo", "-b", "--", "--int=2", "-b" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(parseOk);
			DE_TEST_ASSERT(err.str().empty());

			DE_TEST_ASSERT(cmdLine.getOption<TestStringOpt>() == "foo");
			DE_TEST_ASSERT(cmdLine.getOption<TestBoolOpt>());
			DE_TEST_ASSERT(!cmdLine.hasOption<TestIntOpt>());

			DE_TEST_ASSERT(cmdLine.getArgs().size() == 2);
			DE_TEST_ASSERT(cmdLine.getArgs()[0] == "--int=2");
			DE_TEST_ASSERT(cmdLine.getArgs()[1] == "-b");
		}

		// Value --
		{
			const char*			args[]	= { "--string", "--", "-b", "foo" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(parseOk);
			DE_TEST_ASSERT(err.str().empty());

			DE_TEST_ASSERT(cmdLine.getOption<TestStringOpt>() == "--");
			DE_TEST_ASSERT(cmdLine.getOption<TestBoolOpt>());
			DE_TEST_ASSERT(!cmdLine.hasOption<TestIntOpt>());

			DE_TEST_ASSERT(cmdLine.getArgs().size() == 1);
			DE_TEST_ASSERT(cmdLine.getArgs()[0] == "foo");
		}

		// Invalid flag usage
		{
			const char*			args[]	= { "-b=true" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Invalid named option
		{
			const char*			args[]	= { "-n=two" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Unrecognized option (-x)
		{
			const char*			args[]	= { "-x" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Unrecognized option (--xxx)
		{
			const char*			args[]	= { "--xxx" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Invalid int value
		{
			const char*			args[]	= { "--int", "1x" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Arg specified multiple times
		{
			const char*			args[]	= { "-s=2", "-s=3" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Missing value
		{
			const char*			args[]	= { "--int" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(!parseOk);
			DE_TEST_ASSERT(!err.str().empty());
		}

		// Empty value --arg=
		{
			const char*			args[]	= { "--string=", "-b", "-x", "" };
			CommandLine			cmdLine;
			std::ostringstream	err;
			bool				parseOk	= parser.parse(DE_LENGTH_OF_ARRAY(args), &args[0], &cmdLine, err);

			DE_TEST_ASSERT(parseOk);
			DE_TEST_ASSERT(err.str().empty());
			DE_TEST_ASSERT(cmdLine.getOption<TestStringOpt>() == "");
			DE_TEST_ASSERT(cmdLine.getOption<TestStringDefOpt>() == "");
			DE_TEST_ASSERT(cmdLine.getOption<TestBoolOpt>());
		}
	}
}

} // cmdline
} // de
