#include "parse/enum.hpp"
#include "parse/value.hpp"
#include "std.hpp"
#include "tap.hpp"

int main ()
{
    cruft::TAP::logger tap;

    {
        enum enumeration_t : u16 { FOO, BAR = 2, QUX = 257 };

        auto const cookie = cruft::parse::enumeration::setup<enumeration_t> ({
            { "FOO", FOO },
            { "BAR", BAR },
            { "QUX", QUX },
        });
        (void)cookie;

        tap.expect_eq (FOO, cruft::parse::from_string<enumeration_t> ("FOO"), "enumeration, FOO");
        tap.expect_eq (BAR, cruft::parse::from_string<enumeration_t> ("BAR"), "enumeration, BAR");
        tap.expect_eq (QUX, cruft::parse::from_string<enumeration_t> ("QUX"), "enumeration, QUX");

        tap.expect_eq (
            u16 {QUX},
            cruft::parse::enumeration::from_string<u16> (
                cruft::typeidx<enumeration_t> (),
                "QUX"
            ),
            "u16, QUX"
        );
    }

    {
        enum class enum_class { VALUE };

        auto const cookie = cruft::parse::enumeration::setup<enum_class> ({
            { "VALUE", enum_class::VALUE },
        });
        (void)cookie;

        tap.expect_eq (
            enum_class::VALUE,
            cruft::parse::from_string<enum_class> ("VALUE"), "enum class, VALUE"
        );
    }

    {
        enum class func_enum { ASDF };

        auto const cookie = cruft::parse::enumeration::setup<func_enum> ([] (auto &str) {
            if (equal (str, "ASDF")) {
                str = str.consume (4);
                return func_enum::ASDF;
            }
            throw std::runtime_error ("Invalid enum value");
        });

        (void)cookie;

        tap.expect_eq (
            func_enum::ASDF,
            cruft::parse::from_string<func_enum> ("ASDF"),
            "function enum lookup"
        );
    }

    return tap.status ();
}