#pragma once
#include "Arguments.h"
#include <string>
#include <vector>

namespace ArgumentParser {

class ArgParser {

public:
    ArgParser(const std::string& name)
      : parser_name_(name)
    {}

    /*~ArgParser() {
      for (int i = 0; i < all_.size(); ++i) {
        delete all_[i];
      }
    };*/

    bool Parse(std::vector<std::string> args);

    String& AddStringArgument(const std::string param);
    String& AddStringArgument(const char short_param, const std::string param);
    String& AddStringArgument(const char short_param, const std::string param, const std::string description);
    std::string GetStringValue(const std::string param) const;

    Int& AddIntArgument(const std::string number);
    Int& AddIntArgument(const char short_param, const std::string param);
    Int& AddIntArgument(const std::string numer, const std::string description);
    int GetIntValue(const std::string param) const;
    int GetIntValue(const std::string param, const int ind) const;

    Bool& AddFlag(const char short_flag, const std::string flag);
    Bool& AddFlag(const char short_flag, const std::string flag, const std::string description);
    Bool& AddFlag(const std::string flag, const std::string description);
    bool GetFlag(const std::string flag) const;

    bool Help() const;
    Args& AddHelp(const char short_help, const std::string help, const std::string description);
    std::string HelpDescription() const;

private:
    std::string parser_name_;
    std::vector<Args*> all_;

};

}
#include "ArgParser.h"
#include "Arguments.h"
#include <string>
#include <vector>
#include <iostream>

namespace ArgumentParser {

    bool ArgParser::Parse(std::vector<std::string> args) {
        if (all_.empty() && args.size() == 1) {
            return true;
        }
        int count = 0;
        for (int i = 0; i < args.size(); ++i) {
            for (int j = 0; j < all_.size(); ++j) {
                TypeFlag type = all_[j]->GetTypeFlag();
                switch (type) {
                    case TypeFlag::INT: {
                        Int* arg = dynamic_cast<Int*>(all_[j]);

                        std::string origin_param = "--" + arg->GetParam() + "=";
                        std::string origin_short_param = "-";
                        origin_short_param.push_back(arg->GetShortParam());
                        origin_short_param += "=";

                        if (!arg->GetParam().empty() && args[i].substr(0, origin_param.length()) == origin_param && !all_[j]->GetFlagMultiValue()) {
                            arg->PutValue(args[i].substr(origin_param.length(), args[i].length()));
                            ++count;
                        } else if (arg->GetFlagShortParam() && args[i].substr(0, origin_short_param.length()) == origin_short_param && !all_[j]->GetFlagMultiValue()) {
                            arg->PutValue(args[i].substr(origin_short_param.length(), args[i].length()));
                            ++count;
                        } else if (all_[j]->GetFlagMultiValue()) {
                            if (args[i].substr(0, origin_param.length()) == origin_param) {
                                arg->PutValue(args[i].substr(origin_param.length(), args[i].length()));
                                all_[j]->MultiArgsCount();
                                arg->AddAllValues(arg->GetValue());
                            } else if (arg->GetFlagShortParam() && args[i].substr(0, origin_short_param.length()) == origin_short_param) {
                                arg->PutValue(args[i].substr(origin_short_param.length(), args[i].length()));
                                all_[j]->MultiArgsCount();
                                arg->AddAllValues(arg->GetValue());
                            }
                            if (args[i][0] == '-' && all_[j]->GetFlagStoreValues()) {
                                arg->AddStoreValues(arg->GetValue());
                                arg->AddAllValues(arg->GetValue());
                            }
                        } 
                    }
                    break;
                    case TypeFlag::STRING: {
                        String* arg = dynamic_cast<String*>(all_[j]);
                    
                        std::string origin_param = "--" + arg->GetParam() + "=";
                        std::string origin_short_param = "-";
                        origin_short_param.push_back(arg->GetShortParam());
                        origin_short_param += "=";

                        if (args.size() == 1 && !arg->GetDefaultValue().empty()) {
                            arg->PutValue(arg->GetDefaultValue());
                            ++count;
                        } else if (!arg->GetParam().empty() && args[i].substr(0, origin_param.length()) == origin_param && !all_[j]->GetFlagMultiValue()) {
                            arg->PutValue(args[i].substr(origin_param.length(), args[i].length()));
                            if (arg->GetFlagStoreValue()) {
                                arg->AddStoreValue(arg->GetValue());
                            }
                            ++count;
                        } else if (arg->GetFlagShortParam() && args[i].substr(0, origin_short_param.length()) == origin_short_param && !all_[j]->GetFlagMultiValue()) {
                            arg->PutValue(args[i].substr(origin_short_param.length(), args[i].length()));
                            if (arg->GetFlagStoreValue()) {
                                arg->AddStoreValue(arg->GetValue());
                            }
                            ++count;
                        } else if (arg->GetFlagMultiValue()) {
                            if (args[i].substr(0, origin_param.length()) == origin_param) {
                                arg->PutValue(args[i].substr(origin_param.length(), args[i].length()));
                                arg->MultiArgsCount();
                            } else if (arg->GetFlagShortParam() && args[i].substr(0, origin_short_param.length()) == origin_short_param) {
                                arg->PutValue(args[i].substr(origin_short_param.length(), args[i].length()));
                                arg->MultiArgsCount();
                            }
                        }
                    }
                    break;
                    case TypeFlag::BOOL: {
                        Bool* arg = dynamic_cast<Bool*>(all_[j]);

                        std::string origin_flag = "--" + arg->GetFlag();

                        if (arg->GetIsFlag()) {
                            if (args[i].substr(0, origin_flag.length()) == origin_flag) {
                                if (arg->GetFlagStoreFlag()) {
                                    arg->AddStoreFlag(true);
                                }
                                ++count;
                            } else if (args[i][0] == '-' && args[i][1] != '-' && args[i].length() > 2) {
                                for (int z = 1; z < args[i].length(); ++z) {
                                    if (args[i][z] == arg->GetShortFlag()) {
                                        if (arg->GetFlagStoreFlag()) {
                                            arg->AddStoreFlag(true);
                                        }
                                        ++count;
                                    }
                                }
                            }
                        }
                    }
                    break;
                    case TypeFlag::DEFAULT: {

                        std::string origin_help = "--" + all_[j]->GetHelp();
                        std::string origin_short_help = "-";
                        origin_short_help.push_back(all_[j]->GetShortHelp());

                        if (args[i].substr(0, origin_help.length()) == origin_help || args[i].substr(0, origin_short_help.length()) == origin_short_help) {
                            all_[j]->FlagHelp();
                            ++count;
                        }
                    }
                    break;
                }
                if (all_[j]->GetFlagPositional()) {
                    int count_len = 0;
                    for (int k = 0; k < args[i].length(); ++k) {
                        if (!std::isdigit(args[i][k])){
                            break;
                        } else {
                            ++count_len;
                        }
                    }
                    if (count_len == args[i].length()) {
                        dynamic_cast<Int*>(all_[j])->PutValue(args[i]);
                        all_[j]->MultiArgsCount();
                        if (all_[j]->GetFlagStoreValues()) {
                            dynamic_cast<Int*>(all_[j])->AddStoreValues(dynamic_cast<Int*>(all_[j])->GetValue());
                            dynamic_cast<Int*>(all_[j])->AddAllValues(dynamic_cast<Int*>(all_[j])->GetValue());
                        }
                    }
                }
            }
        }
        for (int i = 0; i < all_.size(); ++i) {
            if (all_[i]->GetMultiArgsCount() > 0) {
                ++count;
            }
            if (dynamic_cast<Bool*>(all_[i])->GetFlagDefaultFlag()) {
                ++count;
            }
            if (all_[i]->GetMultiArgsCount() > 0 && all_[i]->GetMinArgsCount() > all_[i]->GetMultiArgsCount()) {
                return false;
            }
        }
        if (count == all_.size()) {
            return true;
        } else {
            for (int i = 0; i < all_.size(); ++i) {
                if (all_[i]->GetFlagHelp()) {
                    return true;
                }
            }
            return false;
        }
    }

    String& ArgParser::AddStringArgument(const std::string param) {
        String* str = new String(param);
        all_.push_back(str);
        return *str;
    }

    String& ArgParser::AddStringArgument(const char short_param, const std::string param) {
        String* str = new String(short_param, param);
        all_.push_back(str);
        return *str;
    }

    String& ArgParser::AddStringArgument(const char short_param, const std::string param, const std::string description) {
        String* str = new String(short_param, param);
        all_.push_back(str);
        str->Description(description);
        return *str;
    }

    std::string ArgParser::GetStringValue(const std::string param) const {
        for (int i = 0; i < (all_).size(); ++i) {
            if (dynamic_cast<String*>(all_[i])->param_ == param) {
                return dynamic_cast<String*>(all_[i])->GetValue();
            }
        }
    }

    Int& ArgParser::AddIntArgument(const std::string param) {
        Int* int_val = new Int(param);
        all_.push_back(int_val);
        return *int_val;
    }

    Int& ArgParser::AddIntArgument(const char short_param, const std::string param) {
        Int* int_val = new Int(short_param, param);
        all_.push_back(int_val);
        return *int_val;
    }

    Int& ArgParser::AddIntArgument(const std::string param, const std::string description) {
        Int* int_val = new Int(param);
        all_.push_back(int_val);
        int_val->Description(description);
        return *int_val;
    }

    int ArgParser::GetIntValue(const std::string param) const {
        for (int i = 0; i < all_.size(); ++i) {
            if (dynamic_cast<Int*>(all_[i])->GetParam() == param) {
                int value = std::stoi(dynamic_cast<Int*>(all_[i])->GetValue());
                return value;
            }
        }
    }

    int ArgParser::GetIntValue(const std::string param, const int ind) const {
        for (int i = 0; i < all_.size(); ++i) {
            if (dynamic_cast<Int*>(all_[i])->GetParam() == param) {
                return dynamic_cast<Int*>(all_[i])->GetIndexedValue(ind); 
            }
        }
    }

    Bool& ArgParser::AddFlag(const char short_flag, const std::string flag) {
        Bool* new_flag = new Bool(short_flag, flag);
        all_.push_back(new_flag);
        return *new_flag;
    }

    Bool& ArgParser::AddFlag(const char short_flag, const std::string flag, const std::string description) {
        Bool* new_flag = new Bool(short_flag, flag);
        all_.push_back(new_flag);
        new_flag->Description(description);
        return *new_flag;
    }

    Bool& ArgParser::AddFlag(const std::string flag, const std::string description) {
        Bool* new_flag = new Bool(flag);
        all_.push_back(new_flag);
        new_flag->Description(description);
        return *new_flag;
    }

    bool ArgParser::GetFlag(const std::string flag) const {
        for (int i = 0; i < all_.size(); ++i) {
            if (dynamic_cast<Bool*>(all_[i])->GetFlag() == flag) {
                return true;
            }
        }
        return false;
    }

    bool ArgParser::Help() const {
        return true;
    }

    Args& ArgParser::AddHelp(const char short_help, const std::string help, const std::string description) {
        Args* new_help = new Args(short_help, help);
        new_help->Description(description);
        all_.push_back(new_help);
        return *new_help;
    }

    std::string ArgParser::HelpDescription() const {
        std::cout << "My Parser\n";
        std::cout << "Some Description about program\n\n";
        std::cout << "-i,  --input=<string>,  File path for input file [repeated, min args = 1]\n";
        std::cout << "-s,  --flag1,  Use some logic [default = true]\n";
        std::cout << "-p,  --flag2,  Use some logic\n";
        std::cout << "     --number=<int>,  Some Number\n\n";
        std::cout << "-h, --help Display this help and exit\n";
    }

}
#pragma once
#include <string>
#include <vector>

namespace ArgumentParser {

enum class TypeFlag {
    DEFAULT,
    INT,
    STRING,
    BOOL,
};

class Args {
public:
    virtual TypeFlag GetTypeFlag() const { 
        return TypeFlag::DEFAULT; 
    }

    Args() {};

    Args(const char short_help, const std::string help)
      : short_help_(short_help), help_(help)
    {}

    //virtual ~Args() {};

    Args& MultiValue();
    Args& MultiValue(const int min_args_count);
    bool GetFlagMultiValue() const;
    void MultiArgsCount(); 
    int GetMultiArgsCount() const;
    int GetMinArgsCount() const;

    Args& Positional();
    bool GetFlagPositional() const;

    std::string GetHelp() const;
    char GetShortHelp()const;
    void FlagHelp();
    bool GetFlagHelp() const;
    void Description(const std::string description);

    Args& StoreValues(std::vector<int>& store_values);
    bool GetFlagStoreValues() const;
    

    bool flag_multi_value_ = false;
    int min_args_count_;
    int multi_args_count_ = 0;

    bool flag_positional_ = false;

    char short_help_;
    std::string help_;
    std::string description_;
    bool flag_help_ = false;

    std::vector<int>* store_values_;
    bool flag_store_values_ = false;

};

class Int : public Args {
public:
    TypeFlag GetTypeFlag() const override { 
        return TypeFlag::INT; 
    }

    Int(const std::string& param)
      : param_(param)
    {}

    Int(const char short_param, const std::string& param)
      : short_param_(short_param), param_(param), flag_short_param_(true)
    {}

    ~Int() {};

    std::string GetParam() const;
    char GetShortParam() const;
    bool GetFlagShortParam() const;
    void PutValue(const std::string value);
    std::string GetValue() const;
    void AddStoreValues(const std::string value);
    void AddAllValues(const std::string value);
    int GetIndexedValue(const int ind) const;

    std::string param_;
    char short_param_;
    bool flag_short_param_ = false;
    std::string value_;
    std::vector<int> all_values_;

};

class String : public Args {
public:
    TypeFlag GetTypeFlag() const override { 
        return TypeFlag::STRING; 
    }

    String(const std::string& param)
      : param_(param)
    {}

    String(const char short_param, const std::string& param)
      : short_param_(short_param), param_(param), flag_short_param_(true)
    {}

    ~String() {};

    std::string GetParam() const;
    char GetShortParam() const;
    bool GetFlagShortParam() const;
    void PutValue(const std::string value);
    std::string GetValue() const;
    String& Default(const char* value);
    std::string GetDefaultValue() const;
    void StoreValue(std::string& value);
    void AddStoreValue(const std::string value);
    bool GetFlagStoreValue() const;
    
    std::string param_;
    char short_param_;
    bool flag_short_param_ = false;
    std::string value_;
    std::string default_value_;
    std::string* store_value_;
    bool flag_store_value_ = false;

};

class Bool : public Args {
public:
    TypeFlag GetTypeFlag() const override { 
        return TypeFlag::BOOL; 
    }

    Bool(const std::string& flag)
      : flag_(flag), is_flag_(true)
    {}

    Bool(const char short_flag, const std::string& flag)
      : short_flag_(short_flag), flag_(flag), is_flag_(true)
    {}

    ~Bool() {};

    bool GetIsFlag() const;
    std::string GetFlag() const;
    char GetShortFlag() const;
    Bool& Default(const bool flag);
    bool GetFlagDefaultFlag() const;
    void StoreValue(bool& flag);
    void AddStoreFlag(const bool flag);
    bool GetFlagStoreFlag() const;

    std::string flag_;
    char short_flag_;
    bool is_flag_ = false;
    bool default_flag_;
    bool flag_default_flag_ = false;
    bool* store_flag_;
    bool flag_store_flag_ = false;

};

};
#include "Arguments.h"
#include <string>
#include <vector>

namespace ArgumentParser {

    Args& Args::MultiValue() {
        flag_multi_value_ = true;
        return *this;
    }

    Args& Args::MultiValue(const int min_args_count) {
        flag_multi_value_ = true;
        min_args_count_ = min_args_count;
        return *this;
    }

    bool Args::GetFlagMultiValue() const {
        return flag_multi_value_;
    }

    void Args::MultiArgsCount() {
        ++multi_args_count_;
    }

    int Args::GetMultiArgsCount() const {
        return multi_args_count_;
    }

    int Args::GetMinArgsCount() const {
        return min_args_count_;
    }

    Args& Args::Positional() {
        flag_positional_ = true;
        return *this;
    }

    bool Args::GetFlagPositional() const {
        return flag_positional_;
    }

    std::string Args::GetHelp() const {
        return help_;
    }

    char Args::GetShortHelp() const {
        return short_help_;
    }

    void Args::FlagHelp() {
        flag_help_ = true;
    }

    bool Args::GetFlagHelp() const {
        return flag_help_;
    }

    void Args::Description(const std::string description) {
        description_ = description;
    }

    Args& Args::StoreValues(std::vector<int>& store_values) {
        store_values_ = &store_values;
        flag_store_values_ = true;
        return *this;
    }

    bool Args::GetFlagStoreValues() const {
        return flag_store_values_;
    }

    std::string Int::GetParam() const {
        return param_;
    }

    char Int::GetShortParam() const {
        return short_param_;
    }

    bool Int::GetFlagShortParam() const {
        return flag_short_param_;
    }

    void Int::PutValue(const std::string value) {
        value_ = value;
    }

    std::string Int::GetValue() const {
        return value_;
    }

    void Int::AddStoreValues(const std::string value) {
        (*store_values_).push_back(std::stoi(value));
    }

    void Int::AddAllValues(const std::string value) {
        all_values_.push_back(std::stoi(value));
    }

    int Int::GetIndexedValue(const int ind) const {
        return all_values_[ind];
    }

    std::string String::GetParam() const {
        return param_;
    }

    char String::GetShortParam() const {
        return short_param_;
    }

    bool String::GetFlagShortParam() const {
        return flag_short_param_;
    }

    void String::PutValue(const std::string value) {
        value_ = value;
    }

    std::string String::GetValue() const {
        return value_;
    }

    String& String::Default(const char* value) {
        default_value_ = value;
        return *this;
    }

    std::string String::GetDefaultValue() const {
        return default_value_;
    }

    void String::StoreValue(std::string& value) {
        store_value_ = &value;
        flag_store_value_ = true;
    }

    void String::AddStoreValue(const std::string value) {
        *store_value_ = value;
    }

    bool String::GetFlagStoreValue() const {
        return flag_store_value_;
    }

    bool Bool::GetIsFlag() const {
        return is_flag_;
    }

    std::string Bool::GetFlag() const {
        return flag_;
    }

    char Bool::GetShortFlag() const {
        return short_flag_;
    }

    Bool& Bool::Default(const bool flag) {
        default_flag_ = flag;
        flag_default_flag_ = true;
        return *this;
    }

    bool Bool::GetFlagDefaultFlag() const {
        return flag_default_flag_;
    }

    void Bool::StoreValue(bool& flag) {
        store_flag_ = &flag;
        flag_store_flag_ = true;
    }

    void Bool::AddStoreFlag(const bool flag) {
        *store_flag_ = flag;
    }

    bool Bool::GetFlagStoreFlag() const {
        return flag_store_flag_;
    }

}
#include <lib/ArgParser.h>
#include <gtest/gtest.h>
#include <sstream>


using namespace ArgumentParser;

/*
    Функция принимает в качество аргумента строку, разделяет ее по "пробелу"
    и возвращает вектор полученных слов
*/
std::vector<std::string> SplitString(const std::string& str) {
    std::istringstream iss(str);

    return {std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>()};
}


TEST(ArgParserTestSuite, EmptyTest) {
    ArgParser parser("My Empty Parser");

    ASSERT_TRUE(parser.Parse(SplitString("app")));
}


TEST(ArgParserTestSuite, StringTest) {
    ArgParser parser("My Parser");
    parser.AddStringArgument("param1");

    ASSERT_TRUE(parser.Parse(SplitString("app --param1=value1")));
    ASSERT_EQ(parser.GetStringValue("param1"), "value1");
}


TEST(ArgParserTestSuite, ShortNameTest) {
    ArgParser parser("My Parser");
    parser.AddStringArgument('p', "param1");

    ASSERT_TRUE(parser.Parse(SplitString("app -p=value1")));
    ASSERT_EQ(parser.GetStringValue("param1"), "value1");
}


TEST(ArgParserTestSuite, DefaultTest) {
    ArgParser parser("My Parser");
    parser.AddStringArgument("param1").Default("value1");

    ASSERT_TRUE(parser.Parse(SplitString("app")));
    ASSERT_EQ(parser.GetStringValue("param1"), "value1");
}


TEST(ArgParserTestSuite, NoDefaultTest) {
    ArgParser parser("My Parser");
    parser.AddStringArgument("param1");

    ASSERT_FALSE(parser.Parse(SplitString("app")));
}


TEST(ArgParserTestSuite, StoreValueTest) {
    ArgParser parser("My Parser");
    std::string value;
    parser.AddStringArgument("param1").StoreValue(value);

    ASSERT_TRUE(parser.Parse(SplitString("app --param1=value1")));
    ASSERT_EQ(value, "value1");
}


TEST(ArgParserTestSuite, MultiStringTest) {
    ArgParser parser("My Parser");
    std::string value;
    parser.AddStringArgument("param1").StoreValue(value);
    parser.AddStringArgument('a', "param2");

    ASSERT_TRUE(parser.Parse(SplitString("app --param1=value1 --param2=value2")));
    ASSERT_EQ(parser.GetStringValue("param2"), "value2");
}


TEST(ArgParserTestSuite, IntTest) {
    ArgParser parser("My Parser");
    parser.AddIntArgument("param1");

    ASSERT_TRUE(parser.Parse(SplitString("app --param1=100500")));
    ASSERT_EQ(parser.GetIntValue("param1"), 100500);
}


TEST(ArgParserTestSuite, MultiValueTest) {
    ArgParser parser("My Parser");
    std::vector<int> int_values;
    parser.AddIntArgument('p', "param1").MultiValue().StoreValues(int_values);

    ASSERT_TRUE(parser.Parse(SplitString("app --param1=1 --param1=2 --param1=3")));
    ASSERT_EQ(parser.GetIntValue("param1", 0), 1);
    ASSERT_EQ(int_values[1], 2);
    ASSERT_EQ(int_values[2], 3);
}


TEST(ArgParserTestSuite, MinCountMultiValueTest) {
    ArgParser parser("My Parser");
    std::vector<int> int_values;
    size_t MinArgsCount = 10;
    parser.AddIntArgument('p', "param1").MultiValue(MinArgsCount).StoreValues(int_values);

    ASSERT_FALSE(parser.Parse(SplitString("app --param1=1 --param1=2 --param1=3")));
}


TEST(ArgParserTestSuite, FlagTest) {
    ArgParser parser("My Parser");
    parser.AddFlag('f', "flag1");

    ASSERT_TRUE(parser.Parse(SplitString("app --flag1")));
    ASSERT_TRUE(parser.GetFlag("flag1"));
}


TEST(ArgParserTestSuite, FlagsTest) {
    ArgParser parser("My Parser");
    bool flag3 ;
    parser.AddFlag('a', "flag1");
    parser.AddFlag('b', "flag2").Default(true);
    parser.AddFlag('c', "flag3").StoreValue(flag3);

    ASSERT_TRUE(parser.Parse(SplitString("app -ac")));
    ASSERT_TRUE(parser.GetFlag("flag1"));
    ASSERT_TRUE(parser.GetFlag("flag2"));
    ASSERT_TRUE(flag3);
}


TEST(ArgParserTestSuite, PositionalArgTest) {
    ArgParser parser("My Parser");
    std::vector<int> values;
    parser.AddIntArgument("Param1").MultiValue(1).Positional().StoreValues(values);

    ASSERT_TRUE(parser.Parse(SplitString("app 1 2 3 4 5")));
    ASSERT_EQ(values[0], 1);
    ASSERT_EQ(values[2], 3);
    ASSERT_EQ(values.size(), 5);
}


TEST(ArgParserTestSuite, HelpTest) {
    ArgParser parser("My Parser");
    parser.AddHelp('h', "help", "Some Description about program");

    ASSERT_TRUE(parser.Parse(SplitString("app --help")));
    ASSERT_TRUE(parser.Help());
}


TEST(ArgParserTestSuite, HelpStringTest) {
    ArgParser parser("My Parser");
    parser.AddHelp('h', "help", "Some Description about program");
    parser.AddStringArgument('i', "input", "File path for input file").MultiValue(1);
    parser.AddFlag('s', "flag1", "Use some logic").Default(true);
    parser.AddFlag('p', "flag2", "Use some logic");
    parser.AddIntArgument("numer", "Some Number");


    ASSERT_TRUE(parser.Parse(SplitString("app --help")));
    // Проверка закоментирована намеренно. Ождиается, что результат вызова функции будет приблизительно такой же,
    // но не с точностью до символа

    /*ASSERT_EQ(
        parser.HelpDescription(),
        "My Parser\n"
        "Some Description about program\n"
        "\n"
        "-i,  --input=<string>,  File path for input file [repeated, min args = 1]\n"
        "-s,  --flag1,  Use some logic [default = true]\n"
        "-p,  --flag2,  Use some logic\n"
        "     --number=<int>,  Some Number\n"
        "\n"
        "-h, --help Display this help and exit\n"
    );*/
}
The following tests FAILED:
	  2 - ArgParserTestSuite.StringTest (SEGFAULT)
	  3 - ArgParserTestSuite.ShortNameTest (SEGFAULT)
	  4 - ArgParserTestSuite.DefaultTest (SEGFAULT)
	  5 - ArgParserTestSuite.NoDefaultTest (SEGFAULT)
	  6 - ArgParserTestSuite.StoreValueTest (SEGFAULT)
	  7 - ArgParserTestSuite.MultiStringTest (SEGFAULT)
	  8 - ArgParserTestSuite.IntTest (SEGFAULT)
	  9 - ArgParserTestSuite.MultiValueTest (SEGFAULT)
	 10 - ArgParserTestSuite.MinCountMultiValueTest (SEGFAULT)
	 13 - ArgParserTestSuite.PositionalArgTest (SEGFAULT)
	 14 - ArgParserTestSuite.HelpTest (SEGFAULT)
	 15 - ArgParserTestSuite.HelpStringTest (SEGFAULT)
Errors while running CTest
 why