#include "tap.hpp"
#include "view.hpp"

#include <algorithm>


///////////////////////////////////////////////////////////////////////////////
int
main (int, char**)
{
    cruft::TAP::logger tap;

    tap.expect_eq (
        std::size (cruft::make_view ("foo")), 3u,
        "character array view does not include trailing null"
    );

    {
        const std::string s = "this is a test string";
        const std::string t = "not the same string";

        tap.expect_eq  (s, cruft::make_view(s), "string/view equality");
        tap.expect_neq (s, cruft::make_view(t), "string/view inequality");
        tap.expect_eq  (s.data (), cruft::make_view (s), "c-str/view equality");
        tap.expect_eq  (
            s,
            cruft::view<const char*> (&*s.cbegin (), &*s.cend ()),
            "string/pointer-view equality");
    }

    // construction from a std::array
    {
        std::array<std::byte,16> raw;
        cruft::view obj { raw };
        tap.expect_eq (obj.size (), raw.size (), "std::array construction size matches");
    }

    // comparator tests
    {
        static const struct {
            cruft::view<const char*> a;
            cruft::view<const char*> b;
            bool less;
        } TESTS[] = {
            { "b", "b", false },
            { "b", "a", false },
            { "b", "c", true  },
            { "foo", "bar", false },
            { "bar", "foo", true },
            { "banana", "banana", false },
            { "banana", "banan",  false },
            { "banan",  "banana", true  },
        };

        tap.expect (std::all_of (std::begin (TESTS), std::end (TESTS), [] (const auto &x) {
            return (x.a < x.b) == x.less;
        }), "comparator less-than");
    };

    // slicing
    {
        static const struct {
            const char *init;
            const char *result;
            int a;
            int b;
            const char *message;
        } TESTS[] = {
            { "01234567", "01234567", 0,  8, "identity, +ve +ve" },
            { "01234567", "01234567", 0, -1, "identity, +ve -ve" },
            { "01234567", "", -1, -1, "empty, -ve -ve" },
            { "01234567", "45", 4, -3, "centre, +ve -ve" },
        };

        for (const auto &t: TESTS) {
            tap.expect_eq (cruft::view { t.init }.slice (t.a, t.b), t.result, "slice; %s", t.message);
        }
    }

    return tap.status ();
}