/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _CLI_H
#define _CLI_H

#include <algorithm>
#include <exception>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <cassert>
#include <iostream>
#include <numeric>
#include <sstream>
#include <limits>
#include <cstdint>

/**
 * Note this is a hastily hacked together command line parser.
 *
 * I like the syntax of clipp; but it seemed really buggy, and writing something less functional
 * with similar syntax seemed like the quickest way to go.
 *
 * Ironically this is probably just as buggy off the happy path as clipp appeared to be, but
 * in this case the happy path is ours!
 */
namespace cli {

    typedef std::string string;
    template<typename T> using vector = std::vector<T>;
    template<typename A, typename B> using map = std::map<A, B>;
    template<typename A, typename B> using pair = std::pair<A, B>;
    template<typename T> using shared_ptr = std::shared_ptr<T>;

    auto join = [](const vector<string> &range, const string &separator) {
        if (range.empty()) return string();

        return accumulate(
                next(begin(range)), // there is at least 1 element, so OK.
                end(range),

                range[0], // the initial value

                [&separator](auto result, const auto &value) {
                    return result + separator + value;
                });
    };

    struct parse_error : public std::exception {
        explicit parse_error(string what) : _what(std::move(what)) {}

        const char *what() const noexcept override {
            return _what.c_str();
        }

    private:
        string _what;
    };

    struct group;
    template<typename T>
    struct matchable_derived;

    template <typename K, typename V> struct map_and_order {
        map<K,V> _map;
        vector<K> _order;

        V& operator[](const K& key) {
            auto i = _map.find(key);
            if (i == _map.end()) {
                _order.push_back(key);
            }
            return _map[key];
        }

        vector<K> ordered_keys() {
            return _order;
        }
    };

    struct option_map {
        typedef map_and_order<string, map_and_order<string, vector<pair<string, string>>>> container;

        void add(const string& major_group, const string& minor_group, const string& option, const string& description) {
            auto &v = contents[major_group][minor_group];
            // we don't want to repeat the same option
            if (std::find_if(v.begin(), v.end(), [&](const auto &x) { return x.first == option; }) == v.end()) {
                v.emplace_back(option, description);
            }
        }

        container contents;
    };

    struct matchable;

    enum struct match_type {
        not_yet,
        match,
        error,
        no_match,
    };

    struct opaque_settings {
        virtual shared_ptr<opaque_settings> copy() = 0;
        virtual void save_into() = 0;
        virtual void apply_from() = 0;
    };

    struct settings_holder {
        explicit settings_holder(shared_ptr<opaque_settings> settings) : settings(settings) {}
        settings_holder(const settings_holder &other) {
            settings = other.settings->copy();
        }
        settings_holder& operator=(const settings_holder&) = default;
        void save_into() {
            settings->save_into();
        }
        void apply_from() {
            settings->apply_from();
        }
        shared_ptr<opaque_settings> settings;
    };

    struct match_state {
        vector<string> remaining_args;
        string error_message;
        int match_count = 0;
        int error_count = 0;
        // if we are an error for something mising; we should rather report on an up next
        // unsupported option than our error message
        bool prefer_unknown_option_message = false;
        std::map<const matchable *, int> matchable_counts;
        settings_holder settings;

        match_state(const settings_holder& settings) : settings(settings) {}

        void apply_settings_from() {
            settings.apply_from();
        }
        void save_settings_into() {
            settings.save_into();
        }

        match_type match_value(const matchable *matchable, std::function<bool(const string&)> filter);

        match_type check_min_max(const matchable *matchable);

        int get_match_count(const std::shared_ptr<matchable>& element) {
            return matchable_counts[element.get()];
        }

        match_type update_stats(match_type type, const matchable *matchable) {
            assert(type != match_type::not_yet);
            if (type == match_type::match) {
                match_count++;
                matchable_counts[matchable]++;
            } else if (type == match_type::error) {
                error_count++;
                matchable_counts[matchable]++;
            }
            return type;
        }

        match_type match_if_equal(const matchable *matchable, const string& s);
    };

    struct matcher {
    };

    struct matchable {
        matchable() = default;
        virtual ~matchable() = default;

        explicit matchable(string name) : _name(std::move(name)) {}

        std::function<string(string)> action = [](const string&) { return ""; };

        std::function<string()> missing;

        virtual match_type match(match_state& m) const { return match_type::no_match; }

        string name() const {
            return _name;
        }

        virtual std::vector<string> synopsys() const {
            return {_name};
        }

        virtual bool is_optional() const {
            return !_min;
        }

        bool doc_non_optional() const {
            return _doc_non_optional;
        }

        bool force_expand_help() const {
            return _force_expand_help;
        }

        string collapse_synopsys() const {
            return _collapse_synopsys;
        }

        string doc() const {
            return _doc;
        }

        virtual bool get_option_help(string major_group, string minor_group, option_map &options) const {
            return false;
        }

        int min() const {
            return _min;
        }

        int max() const {
            return _max;
        }

    protected:
        string _name;
        string _doc;
        int _min = 1;
        int _max = 1;
        bool _doc_non_optional = false;
        bool _force_expand_help = false;
        string _collapse_synopsys = "";
    };

    template<typename D>
    struct matchable_derived : public matchable {
        matchable_derived() = default;
        explicit matchable_derived(string name) : matchable(std::move(name)) {}

        D &on_action(std::function<string(const string&)> action) {
            this->action = action;
            return *static_cast<D *>(this);
        }

        D &if_missing(std::function<string()> missing) {
            this->missing = missing;
            return *static_cast<D *>(this);
        }

        D &operator%(const string& doc) {
            _doc = doc;
            return *static_cast<D *>(this);
        }

        D &required() {
            _min = 1;
            _max = std::max(_min, _max);
            return *static_cast<D *>(this);
        }

        D &repeatable() {
            _max = std::numeric_limits<int>::max();
            return *static_cast<D *>(this);
        }

        D &min(int v) {
            _min = v;
            return *static_cast<D *>(this);
        }

        D &doc_non_optional(bool v) {
            _doc_non_optional = v;
            return *static_cast<D *>(this);
        }

        D &force_expand_help(bool v) {
            _force_expand_help = v;
            return *static_cast<D *>(this);
        }

        D &collapse_synopsys(string v) {
            _collapse_synopsys = v;
            return *static_cast<D *>(this);
        }

        D &max(int v) {
            _max = v;
            return *static_cast<D *>(this);
        }
        std::shared_ptr<matchable> to_ptr() const {
            return std::shared_ptr<matchable>(new D(*static_cast<const D *>(this)));
        }

        template<typename T>
        group operator&(const matchable_derived<T> &m);
        template<typename T>
        group operator|(const matchable_derived<T> &m);
        template<typename T>
        group operator+(const matchable_derived<T> &m);
    };

    template<typename D>
    struct value_base : public matchable_derived<D> {
        std::function<bool(const string&)> exclusion_filter = [](const string &x){return false;};

        explicit value_base(string name) : matchable_derived<D>(std::move(name)) {
            this->_min = 1;
            this->_max = 1;
        }

        vector<string> synopsys() const override {
            string s = string("<") + this->_name + ">";
            if (this->_max > 1) s += "..";
            return {s};
        }

        bool get_option_help(string major_group, string minor_group, option_map &options) const override {
            if (this->doc().empty()) {
                return false;
            }
            options.add(major_group, minor_group, string("<") + this->_name + ">", this->doc());
            return true;
        }

        match_type match(match_state& ms) const override {
            match_type rc = ms.check_min_max(this);
            if (rc == match_type::not_yet) {
                rc = ms.match_value(this, exclusion_filter);
            }
            return rc;
        }

        D &with_exclusion_filter(std::function<bool(const string&)> exclusion_filter) {
            this->exclusion_filter = exclusion_filter;
            return *static_cast<D *>(this);
        }
    };

    struct option : public matchable_derived<option> {
        explicit option(char short_opt) : option(short_opt, "") {}

        explicit option(string _long_opt) : option(0, std::move(_long_opt)) {}

        option(char _short_opt, string _long_opt) {
            _min = 0;
            short_opt = _short_opt ? "-" + string(1, _short_opt) : "";
            long_opt = std::move(_long_opt);
            _name = short_opt.empty() ? long_opt : short_opt;
        }

        bool get_option_help(string major_group, string minor_group, option_map &options) const override {
            if (doc().empty()) return false;
            string label = short_opt.empty() ? "" : _name;
            if (!long_opt.empty()) {
                if (!label.empty()) label += ", ";
                label += long_opt;
            }
            options.add(major_group, minor_group, label, doc());
            return true;
        }

        template<typename T>
        option &set(T &t) {
            // note we cannot capture "this"
            on_action([&t](const string& value) {
                t = true;
                return "";
            });
            return *this;
        }

        template<typename T>
        option &clear(T &t) {
            // note we cannot capture "this"
            on_action([&t](const string& value) {
                t = false;
                return "";
            });
            return *this;
        }

        match_type match(match_state &ms) const override {
            match_type rc = ms.match_if_equal(this, short_opt);
            if (rc == match_type::no_match) {
                rc = ms.match_if_equal(this, long_opt);
            }
            return rc;
        }

    private:
        string short_opt;
        string long_opt;
    };

    struct value : public value_base<value> {
        explicit value(string name) : value_base(std::move(name)) {}

        template<typename T>
        value &set(T &t) {
            on_action([&](const string& value) {
                t = value;
                return "";
            });
            return *this;
        }
        template<typename T> value &add_to(T &t) {
            // note we cannot capture "this"
            on_action([&t](const string& value) {
                t.push_back(value);
                return "";
            });
            return *this;
        }
    };

    struct integer : public value_base<integer> {
        explicit integer(string name) : value_base(std::move(name)) {}

        template<typename T>
        static std::string parse_string(std::string value, T& out) {
            size_t pos = 0;
            uint64_t lvalue = std::numeric_limits<uint64_t>::max();
            int64_t base = 10;
            if (value.find("0x") == 0) {
                value = value.substr(2);
                base = 16;
            } else if (value.find("0b") == 0) {
                value = value.substr(2);
                base = 2;
            }
            try {
                if (std::is_signed<T>()) {
                    lvalue = std::stoll(value, &pos, base);
                } else {
                    lvalue = std::stoull(value, &pos, base);
                }
                if (pos != value.length()) {
                    return "Garbage after integer value: " + value.substr(pos);
                }
            } catch (std::invalid_argument&) {
                return value + " is not a valid integer";
            } catch (std::out_of_range&) {
                return value + " is out of range";
            }
            if (lvalue != (int64_t)lvalue) {
                return value + " is too big";
            }
            out = (int64_t)lvalue;
            return "";
        }

        template<typename T>
        integer &set(T &t) {
            int64_t min = _min_value;
            int64_t max = _max_value;
            int64_t invalid_bits = _invalid_bits;
            std::string invalid_bits_error = _invalid_bits_error;
            string nm = "<" + name() + ">";
            // note we cannot capture "this"
            on_action([&t, min, max, nm, invalid_bits, invalid_bits_error](const string& value) {
                int64_t tmp = 0;
                std::string err = parse_string(value, tmp);
                t = tmp;
                if (!err.empty()) return err;
                if (t < min) {
                    return nm + " must be >= " + std::to_string(min);
                }
                if (t > max) {
                    return nm + " must be <= " + std::to_string(max);
                }
                if (t & invalid_bits) {
                    return nm + " " + invalid_bits_error;
                }
                return string("");
            });
            return *this;
        }

        template<typename T>
        integer &add_to(T &t) {
            int64_t min = _min_value;
            int64_t max = _max_value;
            int64_t invalid_bits = _invalid_bits;
            std::string invalid_bits_error = _invalid_bits_error;
            string nm = "<" + name() + ">";
            // note we cannot capture "this"
            on_action([&t, min, max, nm, invalid_bits, invalid_bits_error](const string& value) {
                int64_t tmp = 0;
                std::string err = parse_string(value, tmp);
                if (!err.empty()) return err;
                if (tmp < min) {
                    return nm + " must be >= " + std::to_string(min);
                }
                if (tmp > max) {
                    return nm + " must be <= " + std::to_string(max);
                }
                if (tmp & invalid_bits) {
                    return nm + " " + invalid_bits_error;
                }
                t.push_back(tmp);
                return string("");
            });
            return *this;
        }

        integer& min_value(int64_t v) {
            _min_value = v;
            return *this;
        }

        integer& max_value(int64_t v) {
            _max_value = v;
            return *this;
        }

        integer& invalid_bits(int64_t bits, std::string error) {
            _invalid_bits = bits;
            _invalid_bits_error = error;
            return *this;
        }

        int64_t _min_value = 0;
        int64_t _max_value = std::numeric_limits<int64_t>::max();
        std::string _invalid_bits_error;
        int64_t _invalid_bits = 0;
    };

    struct hex : public value_base<hex> {
        explicit hex(string name) : value_base(std::move(name)) {}

        template<typename T>
        hex &set(T &t) {
            unsigned int min = _min_value;
            unsigned int max = _max_value;
            string nm = "<" + name() + ">";
            // note we cannot capture "this"
            on_action([&t, min, max, nm](string value) {
                auto ovalue = value;
                if (value.find("0x") == 0) value = value.substr(2);
                size_t pos = 0;
                long lvalue = std::numeric_limits<long>::max();
                try {
                    lvalue = std::stoul(value, &pos, 16);
                    if (pos != value.length()) {
                        return "Garbage after hex value: " + value.substr(pos);
                    }
                } catch (std::invalid_argument&) {
                    return ovalue + " is not a valid hex value";
                } catch (std::out_of_range&) {
                }
                if (lvalue != (unsigned int)lvalue) {
                    return value + " is not a valid 32 bit value";
                }
                t = (unsigned int)lvalue;
                if (t < min) {
                    std::stringstream ss;
                    ss << nm << " must be >= 0x" << std::hex << std::to_string(min);
                    return ss.str();
                }
                if (t > max) {
                    std::stringstream ss;
                    ss << nm << " must be M= 0x" << std::hex << std::to_string(min);
                    return ss.str();
                }
                return string("");
            });
            return *this;
        }

        template<typename T>
        hex &add_to(T &t) {
            unsigned int min = _min_value;
            unsigned int max = _max_value;
            string nm = "<" + name() + ">";
            // note we cannot capture "this"
            on_action([&t, min, max, nm](string value) {
                auto ovalue = value;
                if (value.find("0x") == 0) value = value.substr(2);
                size_t pos = 0;
                long lvalue = std::numeric_limits<long>::max();
                try {
                    lvalue = std::stoul(value, &pos, 16);
                    if (pos != value.length()) {
                        return "Garbage after hex value: " + value.substr(pos);
                    }
                } catch (std::invalid_argument&) {
                    return ovalue + " is not a valid hex value";
                } catch (std::out_of_range&) {
                }
                if (lvalue != (unsigned int)lvalue) {
                    return value + " is not a valid 32 bit value";
                }
                unsigned int tmp = (unsigned int)lvalue;
                if (tmp < min) {
                    std::stringstream ss;
                    ss << nm << " must be >= 0x" << std::hex << std::to_string(min);
                    return ss.str();
                }
                if (tmp > max) {
                    std::stringstream ss;
                    ss << nm << " must be <= 0x" << std::hex << std::to_string(max);
                    return ss.str();
                }
                t.push_back(tmp);
                return string("");
            });
            return *this;
        }

        hex& min_value(unsigned int v) {
            _min_value = v;
            return *this;
        }

        hex& max_value(unsigned int v) {
            _max_value = v;
            return *this;
        }

        unsigned int _min_value = 0;
        unsigned int _max_value = std::numeric_limits<unsigned int>::max();
    };

    struct group : public matchable_derived<group> {
        enum group_type {
            sequence,
            set,
            exclusive,
            collapse,
        };

    public:
        group() : type(set) {}

        template<typename T>
        explicit group(const T &t) : type(set), elements{t.to_ptr()} {}

        template<class Matchable, class... Matchables>
        group(Matchable m, Matchable ms...) : type(set), elements{m, ms} {}

        group &set_type(group_type t) {
            type = t;
            return *this;
        }

        group &major_group(string g) {
            _major_group = std::move(g);
            return *this;
        }

        static string decorate(const matchable &e, string s) {
            if (e.is_optional() && !e.doc_non_optional()) {
                return string("[") + s + "]";
            } else {
                return s;
            }
        }

        vector<string> synopsys() const override {
            vector<string> rc;
            switch (type) {
                case set:
                case sequence: {
                    std::vector<std::vector<string>> tmp{{}};
                    if (_collapse_synopsys.empty()) {
                        for (auto &x : elements) {
                            auto xs = x->synopsys();
                            if (xs.size() == 1) {
                                for (auto &s : tmp) {
                                    s.push_back(decorate(*x, xs[0]));
                                }
                            } else {
                                auto save = tmp;
                                tmp.clear();
                                for (auto &v : save) {
                                    for (auto &s : xs) {
                                        auto nv = v;
                                        nv.push_back(decorate(*x, s));
                                        tmp.push_back(nv);
                                    }
                                }
                            }
                        }
                    } else {
                        std::vector<std::string> xs = {"[" + _collapse_synopsys + "]"};
                        for (auto &s : tmp) {
                            s.push_back(xs[0]);
                        }
                    }
                    for (const auto &v : tmp) {
                        rc.push_back(join(v, " "));
                    }
                    break;
                }
                case exclusive:
                    for (auto &x : elements) {
                        auto xs = x->synopsys();
                        std::transform(xs.begin(), xs.end(), std::back_inserter(rc), [&](const auto &s) {
                            return decorate(*x, s);
                        });
                    }
                    break;
                default:
                    assert(false);
                    break;
            }
            return rc;
        }

//        group operator|(const group &g) {
//            return matchable_derived::operator|(g);
//        }
//
//        group operator&(const group &g) {
//            return matchable_derived::operator&(g);
//        }
//
//        group operator+(const group &g) {
//            return matchable_derived::operator+(g);
//        }

        bool no_match_beats_error() const {
            return _no_match_beats_error;
        }

        group &no_match_beats_error(bool v) {
            _no_match_beats_error = v;
            return *this;
        }

        template<typename T>
        group operator&(const matchable_derived<T> &m) {
            if (type == sequence) {
                elements.push_back(m.to_ptr());
                return *this;
            }
            return matchable_derived::operator&(m);
        }

        template<typename T>
        group operator|(const matchable_derived<T> &m) {
            if (type == exclusive) {
                elements.push_back(m.to_ptr());
                return *this;
            }
            return matchable_derived::operator|(m);
        }

        template<typename T>
        group operator+(const matchable_derived<T> &m) {
            if (type == set) {
                elements.push_back(m.to_ptr());
                return *this;
            }
            return matchable_derived::operator+(m);
        }

        bool get_option_help(string major_group, string minor_group, option_map &options) const override {
            // todo beware.. this check is necessary as is, but I'm not sure what removing it breaks in terms of formatting  :-(
            if (is_optional() && !this->_doc_non_optional && !this->_force_expand_help) {
                options.add(major_group, minor_group, synopsys()[0], doc());
                return true;
            }
            if (!doc().empty()) {
                minor_group = doc();
            }
            if (!_major_group.empty()) {
                major_group = _major_group;
            }
            for (const auto &e : elements) {
                e->get_option_help(major_group, minor_group, options);
            }
            return true;
        }

        match_type match(match_state& ms) const override {
            match_type rc = ms.check_min_max(this);
            if (rc == match_type::no_match) return rc;
            assert(rc == match_type::not_yet);
            switch(type) {
                case sequence:
                    rc = match_sequence(ms);
                    break;
                case set:
                    rc = match_set(ms);
                    break;
                default:
                    rc = match_exclusive(ms);
                    break;
            }
            return ms.update_stats(rc, this);
        }

        match_type match_sequence(match_state& ms) const {
            match_type rc = match_type::no_match;
            for(const auto& e : elements) {
                rc = e->match(ms);
                assert(rc != match_type::not_yet);
                if (rc != match_type::match) {
                    break;
                }
            }
            return rc;
        }

        match_type match_set(match_state& ms) const {
            // because of repeatability, we keep matching until there is nothing left to match
//            vector<match_type> types(elements.size(), match_type::not_yet);
            bool had_any_matches = false;
            bool final_pass = false;
            do {
                bool matches_this_time = false;
                bool errors_this_time = false;
                bool not_min_this_time = false;
                for (size_t i=0;i<elements.size();i++) {
//                    if (types[i] == match_type::not_yet) {
                        auto ms_prime = ms;
                        ms_prime.apply_settings_from();
                        match_type t = elements[i]->match(ms_prime);
                        assert(t != match_type::not_yet);
                        if (t == match_type::match) {
                            // we got a match, so record in ms and try again
                            // (if the matchable isn't repeatable it will no match next time)
//                            types[i] = match_type::not_yet;
                            ms_prime.save_settings_into();
                            ms = ms_prime;
                            had_any_matches = true;
                            matches_this_time = true;
                        } else if (t == match_type::error) {
                            if (final_pass) {
                                ms_prime.save_settings_into();
                                ms = ms_prime;
                                return t;
                            }
                            errors_this_time = true;
                        } else {
                            if (ms.get_match_count(elements[i]) < elements[i]->min()) {
                                if (final_pass) {
                                    ms.error_message = elements[i]->missing ? elements[i]->missing() : "missing required argument";
                                    return match_type::error;
                                }
                                not_min_this_time = true;
                            }
                        }
//                    }
                }
                if (final_pass) break;
                if (!matches_this_time) {
                    if (errors_this_time || not_min_this_time) {
                        final_pass = true;
                    } else {
                        break;
                    }
                }
            } while (true);
            return had_any_matches ? match_type::match : match_type::no_match;
        }

        match_type match_exclusive(match_state& ms) const {
            vector<match_state> matches(elements.size(), ms);
            vector<match_type> types(elements.size(), match_type::no_match);
            int elements_with_errors = 0;
            int elements_with_no_match = 0;
            int error_at = -1;
            int error_match_count = -1;
            for (size_t i=0;i<elements.size();i++) {
                match_type t;
                matches[i].apply_settings_from();
                do {
                    t = elements[i]->match(matches[i]);
                    assert(t != match_type::not_yet);
                    if (t != match_type::no_match) {
                        types[i] = t;
                    }
                } while (t == match_type::match);
                matches[i].save_settings_into();
                if (types[i] == match_type::match) {
                    ms = matches[i];
                    return match_type::match;
                } else if (types[i] == match_type::error) {
                    if (matches[i].match_count > error_match_count) {
                        error_match_count = matches[i].match_count;
                        error_at = i;
                    }
                    elements_with_errors++;
                } else if (types[i] == match_type::no_match) {
                    elements_with_no_match++;
                }
            }
            if (elements_with_no_match && (!elements_with_errors || no_match_beats_error())) {
                return match_type::no_match;
            }
            if (elements_with_errors) {
                ms = matches[error_at];
                ms.apply_settings_from(); // todo perhaps want to apply the previous settings instead?
                return match_type::error;
            } else {
                // back out any modified settings
                ms.apply_settings_from();
                return match_type::no_match;
            }
        }

    private:
        string _major_group;
        group_type type;
        vector<std::shared_ptr<matchable>> elements;
        bool _no_match_beats_error = true;
    };

    template<typename D>
    template<typename T>
    group matchable_derived<D>::operator|(const matchable_derived<T> &m) {
        return group{this->to_ptr(), m.to_ptr()}.set_type(group::exclusive);
    }

    template<typename D>
    template<typename T>
    group matchable_derived<D>::operator&(const matchable_derived<T> &m) {
        int _min = matchable::min();
        int _max = matchable::max();
        min(1);
        max(1);
        return group{this->to_ptr(), m.to_ptr()}.set_type(group::sequence).min(_min).max(_max);
    }

    template<typename D>
    template<typename T>
    group matchable_derived<D>::operator+(const matchable_derived<T> &m) {
        return group{this->to_ptr(), m.to_ptr()};
    }

    vector<string> make_args(int argc, char **argv) {
        vector<string> args;
        for (int i = 1; i < argc; i++) {
            string arg(argv[i]);
            if (arg.length() > 2 && arg[0] == '-' && arg[1] != '-') {
                // expand collapsed args (unconditionally for now)
                for (auto c = arg.begin() + 1; c != arg.end(); c++) {
                    args.push_back("-" + string(1, *c));
                }
            } else {
                args.push_back(arg);
            }
        }
        return args;
    }

    match_type match_state::check_min_max(const matchable *matchable) {
        if (matchable_counts[matchable] < matchable->min()) {
            return match_type::not_yet;
        }
        if (matchable_counts[matchable] >= matchable->max()) {
            return match_type::no_match;
        }
        return match_type::not_yet;
    }

    match_type match_state::match_if_equal(const matchable *matchable, const string& s) {
        if (remaining_args.empty()) return match_type::no_match;
        if (remaining_args[0] == s) {
            auto message = matchable->action(s);
            assert(message.empty());
            remaining_args.erase(remaining_args.begin());
            return update_stats(match_type::match, matchable);
        }
        return match_type::no_match;
    }

    match_type match_state::match_value(const matchable *matchable, std::function<bool(const string&)> exclusion_filter) {
        // treat an excluded value as missing
        bool empty = remaining_args.empty() || exclusion_filter(remaining_args[0]);
        if (empty) {
            if (matchable_counts[matchable] < matchable->min()) {
                prefer_unknown_option_message = !remaining_args.empty();
                error_message = matchable->missing ? matchable->missing() : "missing <" + matchable->name() +">";
                return update_stats(match_type::error, matchable);
            }
            return match_type::no_match;
        }
        auto message = matchable->action(remaining_args[0]);
        if (!message.empty()) {
            error_message = message;
            return update_stats(match_type::error, matchable);
        }
        remaining_args.erase(remaining_args.begin());
        return update_stats(match_type::match, matchable);
    }

    template<typename S> struct typed_settings final : public opaque_settings {
        explicit typed_settings(S& settings) : root_settings(settings), settings(settings) {
        }

        shared_ptr<cli::opaque_settings> copy() override {
            auto c = std::make_shared<typed_settings<S>>(*this);
            c->settings = settings;
            return c;
        }

        void save_into() override {
            settings = root_settings;
        }

        void apply_from() override {
            root_settings = settings;
        }

        S& root_settings;
        S settings;
    };

    template<typename S> void match(S& settings, const group& g, std::vector<string> args) {
        auto holder = settings_holder(std::make_shared<typed_settings<S>>(settings));
        match_state ms(holder);
        ms.remaining_args = std::move(args);
        auto t = g.match(ms);
        if (!ms.prefer_unknown_option_message) {
            if (t == match_type::error) {
                throw parse_error(ms.error_message);
            }
        }
        if (!ms.remaining_args.empty()) {
            if (ms.remaining_args[0].find('-')==0) {
                throw parse_error("unexpected option: "+ms.remaining_args[0]);
            } else {
                throw parse_error("unexpected argument: "+ms.remaining_args[0]);
            }
        }
        if (ms.prefer_unknown_option_message) {
            if (t == match_type::error) {
                throw parse_error(ms.error_message);
            }
        }
    }
}

#endif
