// Copyright 2018 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 <cstdlib>

#include "test-registry.h"

#include <fbl/function.h>
#include <zxtest/base/assertion.h>
#include <zxtest/base/event-broadcaster.h>
#include <zxtest/base/observer.h>
#include <zxtest/base/runner.h>
#include <zxtest/base/test-case.h>
#include <zxtest/base/test-info.h>
#include <zxtest/base/types.h>

#define ITERATION_EVENT_OBSERVER(Event)                                                            \
    class FakeObserver : public LifecycleObserver {                                                \
    public:                                                                                        \
        void OnIteration##Event(const Runner& runner, int iter) final {                            \
            on_notify(runner, iter);                                                               \
            called = true;                                                                         \
        }                                                                                          \
                                                                                                   \
        fbl::Function<void(const Runner& runner, int iter)> on_notify;                             \
        bool called = false;                                                                       \
    }

#define ASSERTION_OBSERVER                                                                         \
    class FakeObserver : public LifecycleObserver {                                                \
    public:                                                                                        \
        void OnAssertion(const Assertion& assertion) final {                                       \
            on_notify(assertion);                                                                  \
            called = true;                                                                         \
        }                                                                                          \
                                                                                                   \
        fbl::Function<void(const Assertion& assertion)> on_notify;                                 \
        bool called = false;                                                                       \
    }

#define RUNNER_EVENT_OBSERVER(Event)                                                               \
    class FakeObserver : public LifecycleObserver {                                                \
    public:                                                                                        \
        void On##Event(const Runner& runner) final {                                               \
            on_notify(runner);                                                                     \
            called = true;                                                                         \
        }                                                                                          \
                                                                                                   \
        fbl::Function<void(const Runner& runner)> on_notify;                                       \
        bool called = false;                                                                       \
    }

// Defines a FakeObserver class which tracks call to OnTestCaseEvent methods.
#define TESTCASE_EVENT_OBSERVER(Event)                                                             \
    class FakeObserver : public LifecycleObserver {                                                \
    public:                                                                                        \
        void OnTestCase##Event(const TestCase& test_case) final {                                  \
            on_notify(test_case);                                                                  \
            called = true;                                                                         \
        }                                                                                          \
                                                                                                   \
        fbl::Function<void(const TestCase& test_case)> on_notify;                                  \
        bool called = false;                                                                       \
    }

// Defines a FakeObserver class which tracks call to OnTestEvent methods.
#define TEST_EVENT_OBSERVER(Event)                                                                 \
    class FakeObserver : public LifecycleObserver {                                                \
    public:                                                                                        \
        void OnTest##Event(const TestCase& test_case, const TestInfo& info) final {                \
            on_notify(test_case, info);                                                            \
            called = true;                                                                         \
        }                                                                                          \
                                                                                                   \
        fbl::Function<void(const TestCase& test_case, const TestInfo& info)> on_notify;            \
        bool called = false;                                                                       \
    }

// Fills ObserverList with |kNumObservers| instances of |FakeObserver|, which should be defined
// for the scope. And sets on_notify of each observer to on_notify_def and registers them
// with |event_broadcaster|.
#define REGISTER_OBSERVERS(observer_list, event_broadcaster, on_notify_def)                        \
    for (int i = 0; i < kNumObservers; ++i) {                                                      \
        observer_list.push_back({});                                                               \
        auto& observer = observer_list[observer_list.size() - 1];                                  \
        observer.on_notify = on_notify_def;                                                        \
        event_broadcaster.Subscribe(&observer);                                                    \
    }

namespace zxtest {
namespace test {
namespace {

constexpr char kTestCaseName[] = "TestCase";
constexpr char kTestName[] = "Test";

constexpr int kNumObservers = 100;

const SourceLocation kLocation = {.filename = "filename", .line_number = 20};

void Stub() {}

template <typename T> void ValidateAllObserversNotified(const T& observers) {
    for (auto& observer : observers) {
        ZX_ASSERT_MSG(observer.called, "EventBroadcaster failed to propagate event.\n");
    }
}

} // namespace

void EventBroadcasterOnProgramStart() {
    RUNNER_EVENT_OBSERVER(ProgramStart);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(observers, event_broadcaster, [&runner](const Runner& actual_runner) {
        ZX_ASSERT_MSG(&actual_runner == &runner,
                      "EventBroadcaster::OnProgramStart propagated the wrong runner.\n");
    });

    event_broadcaster.OnProgramStart(runner);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnIterationStart() {
    ITERATION_EVENT_OBSERVER(Start);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&runner](const Runner& actual_runner, int iteration) {
            ZX_ASSERT_MSG(&actual_runner == &runner,
                          "EventBroadcaster::OnIterationStart propagated the wrong runner.\n");
            ZX_ASSERT_MSG(
                iteration == 4,
                "EventBroadcaster::OnIterationStart propagated the wron iteration number.\n");
        });

    event_broadcaster.OnIterationStart(runner, 4);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnEnvironmentSetUp() {
    RUNNER_EVENT_OBSERVER(EnvironmentSetUp);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(observers, event_broadcaster, [&runner](const Runner& actual_runner) {
        ZX_ASSERT_MSG(&actual_runner == &runner,
                      "EventBroadcaster::OnEnvironmentSetUp propagated the wrong runner.\n");
    });

    event_broadcaster.OnEnvironmentSetUp(runner);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestCaseStart() {
    TESTCASE_EVENT_OBSERVER(Start);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(observers, event_broadcaster, [&test_case](const TestCase& actual) {
        ZX_ASSERT_MSG(&actual == &test_case,
                      "EventBroadcaster::OnTestCaseStart propagated the wrong test case\n");
    });

    event_broadcaster.OnTestCaseStart(test_case);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestStart() {
    TEST_EVENT_OBSERVER(Start);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    TestInfo test_info(kTestName, kLocation, nullptr);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
            ZX_ASSERT_MSG(&actual == &test_case,
                          "EventBroadcaster::OnTestStart propagated the wrong test case\n");
            ZX_ASSERT_MSG(&actual_info == &test_info,
                          "EventBroadcaster::OnTestStart propagated the wrong test info\n");
        });

    event_broadcaster.OnTestStart(test_case, test_info);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnAssertion() {
    ASSERTION_OBSERVER;

    internal::EventBroadcaster event_broadcaster;
    Assertion assertion("Value should be equal", "kExpectedValue", "5", "actual_value", "10",
                        {.filename = "test.cpp", .line_number = 99999}, /*is_fatal*/ false);
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(observers, event_broadcaster, [&](const Assertion& actual) {
        ZX_ASSERT_MSG(&actual == &assertion,
                      "EventBroadcaster::OnAssertion propagated wrong assertion.\n");
    });

    event_broadcaster.OnAssertion(assertion);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestSkip() {
    TEST_EVENT_OBSERVER(Skip);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    TestInfo test_info(kTestName, kLocation, nullptr);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
            ZX_ASSERT_MSG(&actual == &test_case,
                          "EventBroadcaster::OnTestSkip propagated the wrong test case\n");
            ZX_ASSERT_MSG(&actual_info == &test_info,
                          "EventBroadcaster::OnTestSkip propagated the wrong test info\n");
        });

    event_broadcaster.OnTestSkip(test_case, test_info);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestSuccess() {
    TEST_EVENT_OBSERVER(Success);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    TestInfo test_info(kTestName, kLocation, nullptr);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
            ZX_ASSERT_MSG(&actual == &test_case,
                          "EventBroadcaster::OnTestSuccess propagated the wrong test case\n");
            ZX_ASSERT_MSG(&actual_info == &test_info,
                          "EventBroadcaster::OnTestSuccess propagated the wrong test info\n");
        });

    event_broadcaster.OnTestSuccess(test_case, test_info);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestFailure() {
    TEST_EVENT_OBSERVER(Failure);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    TestInfo test_info(kTestName, kLocation, nullptr);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
            ZX_ASSERT_MSG(&actual == &test_case,
                          "EventBroadcaster::OnTestFailure propagated the wrong test case\n");
            ZX_ASSERT_MSG(&actual_info == &test_info,
                          "EventBroadcaster::OnTestFailure propagated the wrong test info\n");
        });

    event_broadcaster.OnTestFailure(test_case, test_info);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnTestCaseEnd() {
    TESTCASE_EVENT_OBSERVER(End);

    TestCase test_case(kTestCaseName, &Stub, &Stub);
    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);

    REGISTER_OBSERVERS(observers, event_broadcaster, [&test_case](const TestCase& actual) {
        ZX_ASSERT_MSG(&actual == &test_case,
                      "EventBroadcaster::OnTestCaseEnd propagated the wrong test case\n");
    });

    event_broadcaster.OnTestCaseEnd(test_case);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnEnvironmentTearDown() {
    RUNNER_EVENT_OBSERVER(EnvironmentTearDown);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(observers, event_broadcaster, [&runner](const Runner& actual_runner) {
        ZX_ASSERT_MSG(&actual_runner == &runner,
                      "EventBroadcaster::OnIterationStart propagated the wrong runner.\n");
    });

    event_broadcaster.OnEnvironmentTearDown(runner);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnIterationEnd() {
    ITERATION_EVENT_OBSERVER(End);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(
        observers, event_broadcaster, [&runner](const Runner& actual_runner, int iteration) {
            ZX_ASSERT_MSG(&actual_runner == &runner,
                          "EventBroadcaster::OnEnvironmentTearDown propagated the wrong runner.\n");
            ZX_ASSERT_MSG(
                iteration == 4,
                "EventBroadcaster::OnEnvironmentTearDown propagated the wron iteration number.\n");
        });

    event_broadcaster.OnIterationEnd(runner, 4);

    ValidateAllObserversNotified(observers);
}

void EventBroadcasterOnProgramEnd() {
    RUNNER_EVENT_OBSERVER(ProgramEnd);

    internal::EventBroadcaster event_broadcaster;
    fbl::Vector<FakeObserver> observers;
    observers.reserve(kNumObservers);
    Runner runner(Reporter(/*stream*/ nullptr));

    REGISTER_OBSERVERS(observers, event_broadcaster, [&runner](const Runner& actual_runner) {
        ZX_ASSERT_MSG(&actual_runner == &runner,
                      "EventBroadcaster::OnProgramEnd propagated the wrong runner.\n");
    });

    event_broadcaster.OnProgramEnd(runner);

    ValidateAllObserversNotified(observers);
}

} // namespace test
} // namespace zxtest
