/*
 * Copyright (C) 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "Helpers/Test.h"
#include "Helpers/Utilities.h"
#include <wtf/CheckedPtr.h>
#include <wtf/RunLoop.h>
#include <wtf/Threading.h>
#include <wtf/threads/BinarySemaphore.h>

namespace TestWebKitAPI {

static bool testFinished;
static int count = 100;

TEST(WTF_RunLoop, Deadlock)
{
    WTF::initializeMainThread();

    struct DispatchFromDestructorTester {
        ~DispatchFromDestructorTester() {
            RunLoop::mainSingleton().dispatch([] {
                if (!(--count))
                    testFinished = true;
            });
        }
    };

    for (int i = 0; i < count; ++i) {
        auto capture = std::make_shared<DispatchFromDestructorTester>();
        RunLoop::mainSingleton().dispatch([capture] { });
    }

    Util::run(&testFinished);
}

TEST(WTF_RunLoop, NestedInOrder)
{
    WTF::initializeMainThread();

    bool done = false;
    bool didExecuteOuter = false;

    RunLoop::mainSingleton().dispatch([&done, &didExecuteOuter] {
        RunLoop::mainSingleton().dispatch([&done, &didExecuteOuter] {
            EXPECT_TRUE(didExecuteOuter);
            done = true;
        });

        Util::run(&done);
    });
    RunLoop::mainSingleton().dispatch([&didExecuteOuter] {
        didExecuteOuter = true;
    });

    Util::run(&done);
}

TEST(WTF_RunLoop, DispatchCrossThreadWhileNested)
{
    WTF::initializeMainThread();

    bool done = false;

    RunLoop::mainSingleton().dispatch([&done] {
        Thread::create("DispatchCrossThread"_s, [&done] {
            RunLoop::mainSingleton().dispatch([&done] {
                done = true;
            });
        });

        Util::run(&done);
    });
    RunLoop::mainSingleton().dispatch([] { });

    Util::run(&done);
}

TEST(WTF_RunLoop, CallOnMainCrossThreadWhileNested)
{
    WTF::initializeMainThread();

    bool done = false;

    callOnMainThread([&done] {
        Thread::create("CallOnMainCrossThread"_s, [&done] {
            callOnMainThread([&done] {
                done = true;
            });
        });

        Util::run(&done);
    });
    callOnMainThread([] { });

    Util::run(&done);
}

class DerivedOneShotTimer : public CanMakeWeakPtr<DerivedOneShotTimer>, public CanMakeCheckedPtr<DerivedOneShotTimer>, public RunLoop::Timer {
    WTF_DEPRECATED_MAKE_FAST_ALLOCATED(DerivedOneShotTimer);
    WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(DerivedOneShotTimer);
public:
    DerivedOneShotTimer(bool& testFinished)
        : RunLoop::Timer(RunLoop::currentSingleton(), "DerivedOneShotTimer"_s, this, &DerivedOneShotTimer::fired)
        , m_testFinished(testFinished)
    {
    }

    void fired()
    {
        EXPECT_FALSE(isActive());
        EXPECT_EQ(secondsUntilFire(), Seconds(0));

        m_testFinished = true;
        stop();
    }

private:
    bool& m_testFinished;
};


TEST(WTF_RunLoop, OneShotTimer)
{
    WTF::initializeMainThread();

    bool testFinished = false;
    auto timer = makeUniqueRef<DerivedOneShotTimer>(testFinished);
    timer->startOneShot(100_ms);
    Util::run(&testFinished);
}

class DerivedRepeatingTimer : public CanMakeWeakPtr<DerivedRepeatingTimer>, public CanMakeCheckedPtr<DerivedRepeatingTimer>, public RunLoop::Timer {
    WTF_DEPRECATED_MAKE_FAST_ALLOCATED(DerivedRepeatingTimer);
    WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(DerivedRepeatingTimer);
public:
    DerivedRepeatingTimer(bool& testFinished)
        : RunLoop::Timer(RunLoop::currentSingleton(), "DerivedRepeatingTimer"_s, this, &DerivedRepeatingTimer::fired)
        , m_testFinished(testFinished)
    {
    }

    void fired()
    {
        EXPECT_TRUE(isActive());

        if (++m_count == 10) {
            m_testFinished = true;
            stop();

            EXPECT_FALSE(isActive());
            EXPECT_EQ(secondsUntilFire(), Seconds(0));
        }
    }

private:
    unsigned m_count { 0 };
    bool& m_testFinished;
};


TEST(WTF_RunLoop, RepeatingTimer)
{
    WTF::initializeMainThread();

    bool testFinished = false;
    auto timer = makeUniqueRef<DerivedRepeatingTimer>(testFinished);
    timer->startRepeating(10_ms);
    Util::run(&testFinished);
    ASSERT_FALSE(timer->isActive());
}

TEST(WTF_RunLoop, ManyTimes)
{
    class Counter {
    public:
        void run()
        {
            if (++m_count == 100000) {
                RunLoop::currentSingleton().stop();
                return;
            }
            RunLoop::currentSingleton().dispatch([this] {
                run();
            });
        }

    private:
        unsigned m_count { 0 };
    };

    Thread::create("RunLoopManyTimes"_s, [] {
        Counter counter;
        RunLoop::currentSingleton().dispatch([&counter] {
            counter.run();
        });
        RunLoop::run();
    })->waitForCompletion();
}

TEST(WTF_RunLoop, ThreadTerminationSelfReferenceCleanup)
{
    RefPtr<RunLoop> runLoop;

    Thread::create("RunLoopThreadTerminationSelfReferenceCleanup"_s, [&] {
        runLoop = &RunLoop::currentSingleton();

        // This stores a RunLoop reference in the dispatch queue that will not be released
        // via the usual dispatch, but should still be released upon thread termination.
        // After that, the observing RefPtr should be the only one holding a reference
        // to the RunLoop object.
        runLoop->dispatch([ref = runLoop.copyRef()] { });
    })->waitForCompletion();

    EXPECT_TRUE(runLoop->hasOneRef());
}

TEST(WTF_RunLoop, CapabilityIsCurrentIsSupported)
{
    WTF::initializeMainThread();
    struct {
        int i WTF_GUARDED_BY_CAPABILITY(RunLoop::mainSingleton()) { 77 };
    } z;
    assertIsCurrent(RunLoop::mainSingleton());
    bool result = z.i == 77;
    EXPECT_TRUE(result);
}

TEST(WTF_RunLoopDeathTest, MAYBE_ASSERT_ENABLED_DEATH_TEST(CapabilityIsCurrentFailureAsserts))
{
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    ASSERT_DEATH_IF_SUPPORTED({
        WTF::initializeMainThread();
        Thread::create("CapabilityIsCurrentNegative thread"_s, [&] {
            assertIsCurrent(RunLoop::mainSingleton()); // This should assert.
        })->waitForCompletion();
    }, "ASSERTION FAILED: runLoop.isCurrent\\(\\)");
}

TEST(WTF_RunLoop, Create)
{
    RefPtr<RunLoop> runLoop = RunLoop::create("RunLoopCreateTestThread"_s, ThreadType::Unknown);
    Thread* runLoopThread = nullptr;
    {
        BinarySemaphore semaphore;
        runLoop->dispatch([&] {
            runLoopThread = &Thread::currentSingleton();
            semaphore.signal();
        });
        semaphore.wait();
    }

    EXPECT_TRUE(Thread::allThreads().contains(*runLoopThread));

    runLoop->dispatch([] {
        RunLoop::currentSingleton().stop();
    });
    runLoop = nullptr;
    Util::runFor(.2_s);

    // Expect that RunLoop Thread does not leak.
    // Don't use Thread::allThreads().contains(*runLoopThread) here since ASan complains runLoopThread is already freed.
    EXPECT_FALSE(Thread::allThreads().values().containsIf([&](auto& thread) { return thread.ptr() == runLoopThread; }));
}

// FIXME(https://bugs.webkit.org/show_bug.cgi?id=246569): glib and Windows runloop does not match Cocoa.
#if USE(GLIB) || OS(WINDOWS)
#define MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration1 DISABLED_DispatchInRunLoopIterationDispatchesOnNextIteration1
#define MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration2 DISABLED_DispatchInRunLoopIterationDispatchesOnNextIteration2
#else
#define MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration1 DispatchInRunLoopIterationDispatchesOnNextIteration1
#define MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration2 DispatchInRunLoopIterationDispatchesOnNextIteration2
#endif

// Tests that RunLoop::dispatch() respects run loop iteration isolation. E.g. all functions
// dispatched within a run loop iteration will be executed on subsequent iteration.
// Note: At the time of writing, run loop iteration isolation is not respected by 
// RunLoop::dispatchAfter().
TEST(WTF_RunLoop, MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration1)
{
    WTF::initializeMainThread();
    auto& runLoop = RunLoop::currentSingleton();
    bool outer = false;
    bool inner = false;
    int i = 0;
    for (; i < 100; ++i) {
        SCOPED_TRACE(i);
        runLoop.dispatch([&] {
            outer = true;
            runLoop.dispatch([&] {
                inner = true;
            });
            // No matter how long the runloop task takes, all dispatch()es
            // will execute on the next iteration.
            sleep(Seconds { i / 100000. });
        });
        EXPECT_FALSE(outer);
        EXPECT_FALSE(inner);
        runLoop.cycle();
        EXPECT_TRUE(outer);
        EXPECT_FALSE(inner);
        runLoop.cycle();
        EXPECT_TRUE(outer);
        EXPECT_TRUE(inner);
        inner = outer = false;
    }
    // Cleanup local references.
    bool done = false;
    runLoop.dispatch([&] {
        done = true;
    });
    while (!done)
        runLoop.cycle();
}

TEST(WTF_RunLoop, MAYBE_DispatchInRunLoopIterationDispatchesOnNextIteration2)
{
    WTF::initializeMainThread();
    auto& runLoop = RunLoop::currentSingleton();
    int outer = 0;
    int inner = 0;
    int i = 0;
    for (; i < 100; ++i) {
        SCOPED_TRACE(i);
        runLoop.dispatch([&] {
            outer++;
            runLoop.dispatch([&] {
                inner++;
            });
            // No matter how long the runloop task takes, all dispatch()es
            // will execute on the next iteration.
            sleep(Seconds { i / 100000. });
        });
    }
    EXPECT_EQ(outer, 0);
    EXPECT_EQ(inner, 0);
    runLoop.cycle();
    EXPECT_EQ(outer, 100);
    EXPECT_EQ(inner, 0);
    runLoop.cycle();
    EXPECT_EQ(outer, 100);
    EXPECT_EQ(inner, 100);
    // Cleanup local references.
    bool done = false;
    runLoop.dispatch([&] {
        done = true;
    });
    while (!done)
        runLoop.cycle();
}

} // namespace TestWebKitAPI
