/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/private/SkTemplates.h"
#include "tests/Test.h"

#include <cstddef>
#include <utility>

using namespace skia_private;

// Tests for some of the helpers in SkTemplates.h
static void test_automalloc_realloc(skiatest::Reporter* reporter) {
    AutoSTMalloc<1, int> array;

    // test we have a valid pointer, should not crash
    array[0] = 1;
    REPORTER_ASSERT(reporter, array[0] == 1);

    // using realloc for init
    array.realloc(1);

    array[0] = 1;
    REPORTER_ASSERT(reporter, array[0] == 1);

    // verify realloc can grow
    array.realloc(2);
    REPORTER_ASSERT(reporter, array[0] == 1);

    // realloc can shrink
    array.realloc(1);
    REPORTER_ASSERT(reporter, array[0] == 1);

    // should not crash
    array.realloc(0);

    // grow and shrink again
    array.realloc(10);
    for (int i = 0; i < 10; i++) {
        array[i] = 10 - i;
    }
    array.realloc(20);
    for (int i = 0; i < 10; i++) {
        REPORTER_ASSERT(reporter, array[i] == 10 - i);
    }
    array.realloc(10);
    for (int i = 0; i < 10; i++) {
        REPORTER_ASSERT(reporter, array[i] == 10 - i);
    }

    array.realloc(1);
    REPORTER_ASSERT(reporter, array[0] = 10);

    // resets mixed with realloc, below stack alloc size
    array.reset(0);
    array.realloc(1);
    array.reset(1);

    array[0] = 1;
    REPORTER_ASSERT(reporter, array[0] == 1);

    // reset and realloc > stack size
    array.reset(2);
    array.realloc(3);
    array[0] = 1;
    REPORTER_ASSERT(reporter, array[0] == 1);
    array.realloc(1);
    REPORTER_ASSERT(reporter, array[0] == 1);
}

DEF_TEST(Templates, reporter) {
    test_automalloc_realloc(reporter);
}

constexpr int static kStackPreallocCount = 10;

// Ensures the containers in SkTemplates.h all have a consistent api.
template<typename TContainer, typename TCount>
static void test_container_apis(skiatest::Reporter* reporter) {
    REPORTER_ASSERT(reporter, !TContainer((TCount)0).get());
    REPORTER_ASSERT(reporter, !TContainer((TCount)0).data());
    REPORTER_ASSERT(reporter, TContainer((TCount)1).get());
    REPORTER_ASSERT(reporter, TContainer((TCount)1).data());
    REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).get());
    REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).data());
    REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).get());
    REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).data());

    TContainer container;
    // The default constructor may or may not init to empty, depending on the type of container.

    auto fillToN = [](TContainer& c, int n) -> void {
        for (int i = 0; i < n; ++i) {
            c[i] = n;
        }
    };
    auto isFillToN = [](const TContainer& c, int n) -> bool {
        for (int i = 0; i < n; ++i) {
            if (c[i] != n) { return false; }
        }
        return true;
    };

    {
        container.reset((TCount)1);
        fillToN(container, 1);
        REPORTER_ASSERT(reporter, container.get());
        REPORTER_ASSERT(reporter, container.get() == container.data());
        REPORTER_ASSERT(reporter, isFillToN(container, 1));
        TContainer m(std::move(container));
        REPORTER_ASSERT(reporter, isFillToN(m, 1));
    }

    {
        container.reset((TCount)kStackPreallocCount);
        fillToN(container, kStackPreallocCount);
        REPORTER_ASSERT(reporter, container.get());
        REPORTER_ASSERT(reporter, container.get() == container.data());
        REPORTER_ASSERT(reporter, isFillToN(container, kStackPreallocCount));
        TContainer m(std::move(container));
        REPORTER_ASSERT(reporter, isFillToN(m, kStackPreallocCount));
    }

    {
        container.reset((TCount)kStackPreallocCount + 1);
        fillToN(container, kStackPreallocCount + 1);
        REPORTER_ASSERT(reporter, container.get());
        REPORTER_ASSERT(reporter, container.get() == container.data());
        REPORTER_ASSERT(reporter, isFillToN(container, kStackPreallocCount + 1));
        TContainer m(std::move(container));
        REPORTER_ASSERT(reporter, isFillToN(m, kStackPreallocCount + 1));
    }

    {
        container.reset((TCount)0);
        REPORTER_ASSERT(reporter, !container.get());
        REPORTER_ASSERT(reporter, !container.data());
        TContainer m(std::move(container));
        REPORTER_ASSERT(reporter, !m.get());
        REPORTER_ASSERT(reporter, !m.data());
    }
}

DEF_TEST(TemplateContainerAPIsTrim, reporter) {
    AutoSTArray<kStackPreallocCount, int> c;
    c.trimTo(100);
    REPORTER_ASSERT(reporter, c.size() == 0);
    c.trimTo(1);
    REPORTER_ASSERT(reporter, c.size() == 0);
    c.trimTo(0);
    REPORTER_ASSERT(reporter, c.size() == 0);

    c.reset(1);
    REPORTER_ASSERT(reporter, c.size() == 1);
    c.trimTo(2);
    REPORTER_ASSERT(reporter, c.size() == 1);
    c.trimTo(1);
    REPORTER_ASSERT(reporter, c.size() == 1);
    c.trimTo(0);
    REPORTER_ASSERT(reporter, c.size() == 0);
}

DEF_TEST(TemplateContainerAPIs, reporter) {
    test_container_apis<AutoTArray<int>, int>(reporter);
    test_container_apis<AutoSTArray<kStackPreallocCount, int>, int>(reporter);
    test_container_apis<AutoTMalloc<int>, size_t>(reporter);
    test_container_apis<AutoSTMalloc<kStackPreallocCount, int>, size_t>(reporter);
}

// Ensures that realloc(0) results in a null pointer.
template<typename TAutoMalloc> static void test_realloc_to_zero(skiatest::Reporter* reporter) {
    TAutoMalloc autoMalloc(kStackPreallocCount);
    REPORTER_ASSERT(reporter, autoMalloc.get());

    autoMalloc.realloc(0);
    REPORTER_ASSERT(reporter, !autoMalloc.get());

    autoMalloc.realloc(kStackPreallocCount + 1);
    REPORTER_ASSERT(reporter, autoMalloc.get());

    autoMalloc.realloc(0);
    REPORTER_ASSERT(reporter, !autoMalloc.get());

    autoMalloc.realloc(kStackPreallocCount);
    REPORTER_ASSERT(reporter, autoMalloc.get());
}

DEF_TEST(AutoReallocToZero, reporter) {
    test_realloc_to_zero<AutoTMalloc<int> >(reporter);
    test_realloc_to_zero<AutoSTMalloc<kStackPreallocCount, int> >(reporter);
}

DEF_TEST(AutoTMallocSelfMove, r) {
#if defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wself-move"
#elif defined(__GNUC__) && __GNUC__ >= 13
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wself-move"
#endif

    AutoTMalloc<int> foo(20);
    REPORTER_ASSERT(r, foo.get());

    foo = std::move(foo);
    REPORTER_ASSERT(r, foo.get());  // NOLINT(bugprone-use-after-move)

#if defined(__clang__)
    #pragma clang diagnostic pop
#elif defined(__GNUC__) && __GNUC__ >= 13
    #pragma GCC diagnostic pop
#endif
}
