#pragma once

#include "chocolat/system/option_parser.hpp"
#include "chocolat/system/file_path.hpp"
#include "chocolat/string/number_format.hpp"


/** using character option parser */
class ApplicationOption
{
public:
	bool is_argument_failure;
	FilePath file_name;
	std::string bad_option;
	
	unsigned start_address;
	bool has_start_address;
	bool is_display_hex_dump;
	bool is_display_assembly;
	bool is_display_quadruple;
	bool is_display_basic_block;
	bool is_display_routine;
	bool is_display_dominator;
	
	ApplicationOption(int argc, char** argv)
			:is_argument_failure(false),
			 start_address(0x100000),
			 has_start_address(false),
			 is_display_hex_dump(false),
			 is_display_assembly(false),
			 is_display_quadruple(false),
			 is_display_basic_block(false),
			 is_display_routine(false),
			 is_display_dominator(false)
	{
		std::string program_name = argv[0];
		
		CharacterOptionParser opt("s:xaqbrd");
		
		opt.parse(argc, argv);
		if (opt.bad()) {
			is_argument_failure = true;
			bad_option = opt.bad_options[0];
			return;
		}
		
		for (auto i=opt.begin(); i!=opt.end(); ++i) {
			switch (i->option()){
			case 's':
				has_start_address = true;
				start_address = HexadecimalFormat(i->argument());
				break;
			case 'x':
				is_display_hex_dump = true; break;
			case 'a':
				is_display_assembly = true; break;
			case 'q':
				is_display_quadruple = true; break;
			case 'b':
				is_display_basic_block = true; break;
			case 'r':
				is_display_routine = true; break;
			case 'd':
				is_display_dominator = true; break;
			default:
				is_argument_failure=true;
				return;
			}
		}
		if (opt.rest_arguments.size() != 1
			|| opt.bad_options.size()>0){
			is_argument_failure=true;
			return;
		}
		file_name = opt.rest_arguments[0];
	}
	bool bad()const
	{
		return is_argument_failure;
	}
	void dump(std::ostream& os)const;
};
void
inline ApplicationOption::dump(std::ostream& os)const
{
	os << "good: " << !is_argument_failure << std::endl;
}
