#ifndef _DECOMMANDLINE_HPP
#define _DECOMMANDLINE_HPP
/*-------------------------------------------------------------------------
 * 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 "deDefs.hpp"

#include <map>
#include <string>
#include <vector>
#include <ostream>
#include <typeinfo>
#include <stdexcept>

namespace de
{
namespace cmdline
{

//! Default parsing function
template<typename ValueType>
void parseType (const char* src, ValueType* dst);

template<typename T>
struct NamedValue
{
	const char*	name;
	T			value;
};

template<typename OptName>
struct Option
{
	typedef typename OptName::ValueType ValueType;
	typedef void (*ParseFunc) (const char* src, ValueType* dst);

	// \note All assumed to point to static memory.
	const char*						shortName;
	const char*						longName;
	const char*						description;
	const char*						defaultValue;		//!< Default value (parsed from string), or null if should not be set

	// \note Either parse or namedValues must be null.
	ParseFunc						parse;				//!< Custom parsing function or null.
	const NamedValue<ValueType>*	namedValues;		//!< Named values or null.
	const NamedValue<ValueType>*	namedValuesEnd;		//!< Named value list end.

	//! Construct generic option (string, int, boolean).
	Option (const char* shortName_, const char* longName_, const char* description_, const char* defaultValue_ = DE_NULL)
		: shortName		(shortName_)
		, longName		(longName_)
		, description	(description_)
		, defaultValue	(defaultValue_)
		, parse			(parseType<ValueType>)
		, namedValues	(DE_NULL)
		, namedValuesEnd(0)
	{
	}

	//! Option with custom parsing function.
	Option (const char* shortName_, const char* longName_, const char* description_, ParseFunc parse_, const char* defaultValue_ = DE_NULL)
		: shortName		(shortName_)
		, longName		(longName_)
		, description	(description_)
		, defaultValue	(defaultValue_)
		, parse			(parse_)
		, namedValues	(DE_NULL)
		, namedValuesEnd(DE_NULL)
	{
	}

	//! Option that uses named values.
	Option (const char* shortName_, const char* longName_, const char* description_, const NamedValue<ValueType>* namedValues_, const NamedValue<ValueType>* namedValuesEnd_, const char* defaultValue_ = DE_NULL)
		: shortName		(shortName_)
		, longName		(longName_)
		, description	(description_)
		, defaultValue	(defaultValue_)
		, parse			((ParseFunc)DE_NULL)
		, namedValues	(namedValues_)
		, namedValuesEnd(namedValuesEnd_)
	{
	}

	//! Option that uses named values.
	template<size_t NumNamedValues>
	Option (const char* shortName_, const char* longName_, const char* description_, const NamedValue<ValueType> (&namedValues_)[NumNamedValues], const char* defaultValue_ = DE_NULL)
		: shortName		(shortName_)
		, longName		(longName_)
		, description	(description_)
		, defaultValue	(defaultValue_)
		, parse			((ParseFunc)DE_NULL)
		, namedValues	(DE_ARRAY_BEGIN(namedValues_))
		, namedValuesEnd(DE_ARRAY_END(namedValues_))
	{
	}
};

template<class Option>
struct OptTraits
{
	typedef typename Option::ValueType ValueType;
};

//! Default value lookup
template<typename ValueType>
inline void getTypeDefault (ValueType* dst)
{
	*dst = ValueType();
}

template<> void getTypeDefault<bool> (bool* dst);

template<typename T>	inline bool isBoolean		(void) { return false;	}
template<>				inline bool isBoolean<bool>	(void) { return true;	}

//! Is argument boolean-only value?
template<class Option>	inline bool isBooleanOpt	(void) { return isBoolean<typename OptTraits<Option>::ValueType>(); }

namespace detail
{

using std::string;
using std::vector;
using std::map;

// TypedFieldMap implementation

template<class Name>
struct TypedFieldTraits
{
	// Generic implementation for cmdline.
	typedef typename OptTraits<Name>::ValueType	ValueType;
};

template<class Value>
struct TypedFieldValueTraits
{
	static void destroy (void* value) { delete (Value*)value; }
};

class TypedFieldMap
{
public:
						TypedFieldMap			(void);
						~TypedFieldMap			(void);

	bool				empty					(void) const	{ return m_fields.empty();	}
	void				clear					(void);

	template<typename Name>
	void				set						(typename TypedFieldTraits<Name>::ValueType* value);

	template<typename Name>
	void				set						(const typename TypedFieldTraits<Name>::ValueType& value);

	template<typename Name>
	bool				contains				(void) const;

	template<typename Name>
	const typename TypedFieldTraits<Name>::ValueType&
						get						(void) const;

private:
						TypedFieldMap			(const TypedFieldMap&);
	TypedFieldMap&		operator=				(const TypedFieldMap&);

	typedef void (*DestroyFunc) (void*);

	struct Entry
	{
		void*			value;
		DestroyFunc		destructor;

		Entry (void) : value(DE_NULL), destructor(0) {}
		Entry (void* value_, DestroyFunc destructor_) : value(value_), destructor(destructor_) {}
	};

	typedef std::map<const std::type_info*, Entry> Map;

	bool				contains				(const std::type_info* key) const;
	const Entry&		get						(const std::type_info* key) const;
	void				set						(const std::type_info* key, const Entry& value);

	Map					m_fields;
};

template<typename Name>
inline void TypedFieldMap::set (typename TypedFieldTraits<Name>::ValueType* value)
{
	set(&typeid(Name), Entry(value, &TypedFieldValueTraits<typename TypedFieldTraits<Name>::ValueType>::destroy));
}

template<typename Name>
void TypedFieldMap::set (const typename TypedFieldTraits<Name>::ValueType& value)
{
	typename TypedFieldTraits<Name>::ValueType* copy = new typename TypedFieldTraits<Name>::ValueType(value);

	try
	{
		set<Name>(copy);
	}
	catch (...)
	{
		delete copy;
		throw;
	}
}

template<typename Name>
inline bool TypedFieldMap::contains (void) const
{
	return contains(&typeid(Name));
}

template<typename Name>
inline const typename TypedFieldTraits<Name>::ValueType& TypedFieldMap::get (void) const
{
	return *static_cast<typename TypedFieldTraits<Name>::ValueType*>(get(&typeid(Name)).value);
}

class CommandLine;

typedef void (*GenericParseFunc) (const char* src, void* dst);

class Parser
{
public:
					Parser				(void);
					~Parser				(void);

	template<class OptType>
	void			addOption			(const Option<OptType>& option);

	bool			parse				(int numArgs, const char* const* args, CommandLine* dst, std::ostream& err) const;

	void			help				(std::ostream& dst) const;

private:
					Parser				(const Parser&);
	Parser&			operator=			(const Parser&);

	struct OptInfo;

	typedef void		(*DispatchParseFunc)		(const OptInfo* info, const char* src, TypedFieldMap* dst);
	typedef void		(*SetDefaultFunc)			(TypedFieldMap* dst);

	struct OptInfo
	{
		const char*				shortName;
		const char*				longName;
		const char*				description;
		const char*				defaultValue;
		bool					isFlag;			//!< Set true for bool typed arguments that do not used named values.

		GenericParseFunc		parse;

		const void*				namedValues;
		const void*				namedValuesEnd;
		size_t					namedValueStride;

		DispatchParseFunc		dispatchParse;
		SetDefaultFunc			setDefault;

		OptInfo (void)
			: shortName			(DE_NULL)
			, longName			(DE_NULL)
			, description		(DE_NULL)
			, defaultValue		(DE_NULL)
			, isFlag			(false)
			, parse				(DE_NULL)
			, namedValues		(DE_NULL)
			, namedValuesEnd	(DE_NULL)
			, namedValueStride	(0)
			, dispatchParse		(DE_NULL)
			, setDefault		(DE_NULL)
		{}
	};

	void			addOption			(const OptInfo& option);

	template<typename OptName>
	static void		dispatchParse		(const OptInfo* info, const char* src, TypedFieldMap* dst);

	vector<OptInfo>	m_options;
};

template<class OptType>
inline Parser& operator<< (Parser& parser, const Option<OptType>& option)
{
	parser.addOption(option);
	return parser;
}

//! Find match by name. Throws exception if no match is found.
const void* findNamedValueMatch (const char* src, const void* namedValues, const void* namedValuesEnd, size_t stride);

template<typename OptType>
void Parser::dispatchParse (const OptInfo* info, const char* src, TypedFieldMap* dst)
{
	typename OptTraits<OptType>::ValueType* value = new typename OptTraits<OptType>::ValueType();
	try
	{
		DE_ASSERT((!!info->parse) != (!!info->namedValues));
		if (info->parse)
		{
			((typename Option<OptType>::ParseFunc)(info->parse))(src, value);
		}
		else
		{
			const void* match = findNamedValueMatch(src, info->namedValues, info->namedValuesEnd, info->namedValueStride);
			*value = static_cast<const NamedValue<typename OptTraits<OptType>::ValueType>*>(match)->value;
		}
		dst->set<OptType>(value);
	}
	catch (...)
	{
		delete value;
		throw;
	}
}

template<typename OptType>
void dispatchSetDefault (TypedFieldMap* dst)
{
	typename OptTraits<OptType>::ValueType* value = new typename OptTraits<OptType>::ValueType();
	try
	{
		getTypeDefault<typename OptTraits<OptType>::ValueType>(value);
		dst->set<OptType>(value);
	}
	catch (...)
	{
		delete value;
		throw;
	}
}

template<typename OptType>
const char* getNamedValueName (const void* value)
{
	const NamedValue<typename OptTraits<OptType>::ValueType>* typedVal = static_cast<const NamedValue<typename OptTraits<OptType>::ValueType> >(value);
	return typedVal->name;
}

template<typename OptType>
void setFromNamedValue (const void* value, TypedFieldMap* dst)
{
	const NamedValue<typename OptTraits<OptType>::ValueType>* typedVal = static_cast<const NamedValue<typename OptTraits<OptType>::ValueType> >(value);
	dst->set<OptType>(typedVal->value);
}

template<class OptType>
void Parser::addOption (const Option<OptType>& option)
{
	OptInfo opt;

	opt.shortName			= option.shortName;
	opt.longName			= option.longName;
	opt.description			= option.description;
	opt.defaultValue		= option.defaultValue;
	opt.isFlag				= isBooleanOpt<OptType>() && !option.namedValues;
	opt.parse				= (GenericParseFunc)option.parse;
	opt.namedValues			= (const void*)option.namedValues;
	opt.namedValuesEnd		= (const void*)option.namedValuesEnd;
	opt.namedValueStride	= sizeof(*option.namedValues);
	opt.dispatchParse		= dispatchParse<OptType>;

	if (opt.isFlag)
		opt.setDefault		= dispatchSetDefault<OptType>;

	addOption(opt);
}

class CommandLine
{
public:
								CommandLine		(void) {}
								~CommandLine	(void) {}

	void						clear			(void);

	const TypedFieldMap&		getOptions		(void) const	{ return m_options;	}
	const vector<string>&		getArgs			(void) const	{ return m_args;	}

	template<typename Option>
	bool						hasOption		(void) const	{ return m_options.contains<Option>();	}

	template<typename Option>
	const typename TypedFieldTraits<Option>::ValueType&
								getOption		(void) const	{ return m_options.get<Option>();		}

private:
	TypedFieldMap				m_options;
	vector<string>				m_args;

	friend class Parser;
};

} // detail

using detail::Parser;
using detail::CommandLine;

void selfTest (void);

} // cmdline
} // de

#define DE_DECLARE_COMMAND_LINE_OPT(NAME, TYPE) struct NAME { typedef TYPE ValueType; }

#endif // _DECOMMANDLINE_HPP
