// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/lazy_init/lazy_init.h>
#include <unittest/unittest.h>
#include <zircon/compiler.h>

#include <atomic>
#include <cstring>

using lazy_init::CheckType;
using lazy_init::Destructor;
using lazy_init::LazyInit;

namespace {

template <auto...>
struct TestType {
    TestType() {
        constructions_++;
    }
    ~TestType() {
        destructions_++;
    }

    TestType(const TestType&) = delete;
    TestType& operator=(const TestType&) = delete;

    void Method() {}

    static size_t constructions() {
        return constructions_.load();
    }
    static size_t destructions() {
        return destructions_.load();
    }

    inline static std::atomic<size_t> constructions_;
    inline static std::atomic<size_t> destructions_;
};

template <typename T>
union Storage {
    constexpr Storage()
        : value{} {}
    ~Storage() {}

    int dummy;
    T value;
};

template <CheckType Check, Destructor Enabled>
bool lazy_init_test() {
    BEGIN_TEST;

    // Define a unique test type for this test instantiation.
    using Type = TestType<Check, Enabled>;

    // Define a lazy-initialized variable for this test. Normally this
    // would be a static or global, but for this test we need to control
    // when the dtor is executed and avoid asserting at the end of the test
    // process when global dtors run.
    using LazyInitType = LazyInit<Type, Check, Enabled>;

    static Storage<LazyInitType> test_value_storage{};
    LazyInitType& test_value = test_value_storage.value;

    size_t expected_constructions = 0;
    size_t expected_destructions = 0;

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    const auto dereference_test = [](void* arg) {
        auto& lazy = *static_cast<LazyInitType*>(arg);
        lazy->Method();
    };

    if (Check != CheckType::None) {
        ASSERT_DEATH(dereference_test, &test_value,
                     "Testing assert before initialization.\n");
    } else {
        ASSERT_NO_DEATH(dereference_test, &test_value,
                        "Testing assert before initialization.\n");
    }

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    const auto initialization_test = [](void* arg) {
        auto& lazy = *static_cast<LazyInitType*>(arg);
        lazy.Initialize();
    };

    ASSERT_NO_DEATH(initialization_test, &test_value,
                    "Testing intialization.\n");
    ++expected_constructions;

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    if (Check == CheckType::None) {
        ASSERT_NO_DEATH(initialization_test, &test_value,
                        "Testing re-intialization.\n");
        ++expected_constructions;
    } else {
        ASSERT_DEATH(initialization_test, &test_value,
                     "Testing re-intialization.\n");
    }

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    ASSERT_NO_DEATH(dereference_test, &test_value,
                    "Testing assert after initialization.\n");

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    const auto destruction_test = [](void* arg) {
        auto& lazy = *static_cast<LazyInitType*>(arg);
        lazy.LazyInitType::~LazyInitType();
    };

    ASSERT_NO_DEATH(destruction_test, &test_value, "Testing destruction.\n");

    if (Enabled == Destructor::Enabled) {
        ++expected_destructions;
    }

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    if (Check == CheckType::None || Enabled == Destructor::Disabled) {
        ASSERT_NO_DEATH(dereference_test, &test_value,
                        "Testing assert after destruction.\n");
    } else {
        ASSERT_DEATH(dereference_test, &test_value,
                     "Testing assert after destruction.\n");
    }

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    if (Check == CheckType::None || Enabled == Destructor::Disabled) {
        ASSERT_NO_DEATH(destruction_test, &test_value,
                        "Testing re-destruction.\n");
        if (Enabled == Destructor::Enabled) {
            ++expected_destructions;
        }
    } else {
        ASSERT_DEATH(destruction_test, &test_value,
                     "Testing re-destruction.\n");
    }

    EXPECT_EQ(expected_constructions, Type::constructions());
    EXPECT_EQ(expected_destructions, Type::destructions());

    END_TEST;
}

// TODO(eieio): Does it make sense to try to create races to test the atomic
// check specialization more thoroughly?

} // anonymous namespace

BEGIN_TEST_CASE(lazy_init_tests)
RUN_NAMED_TEST("Lazy init (no checks / no dtor)",
               (lazy_init_test<CheckType::None, Destructor::Disabled>))
RUN_NAMED_TEST("Lazy init (basic checks / no dtor)",
               (lazy_init_test<CheckType::Basic, Destructor::Disabled>))
RUN_NAMED_TEST("Lazy init (atomic checks / no dtor)",
               (lazy_init_test<CheckType::Atomic, Destructor::Disabled>))
RUN_NAMED_TEST("Lazy init (no checks / with dtor)",
               (lazy_init_test<CheckType::None, Destructor::Enabled>))
RUN_NAMED_TEST("Lazy init (basic checks / with dtor)",
               (lazy_init_test<CheckType::Basic, Destructor::Enabled>))
RUN_NAMED_TEST("Lazy init (atomic checks / with dtor)",
               (lazy_init_test<CheckType::Atomic, Destructor::Enabled>))
END_TEST_CASE(lazy_init_tests)
