/*
 * Copyright (C) 2018 Igalia, S.L.
 * Copyright (C) 2018 Metrological Group B.V.
 *
 * 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 "Utilities.h"
#include <WebCore/AbortableTaskQueue.h>
#include <wtf/Threading.h>

using namespace WebCore;

namespace TestWebKitAPI {

TEST(AbortableTaskQueue, AsyncTasks)
{
    AbortableTaskQueue taskQueue;
    bool testFinished { false };
    int currentStep { 0 };
    WTF::initializeMainThread();

    auto backgroundThreadFunction = [&]() {
        EXPECT_FALSE(isMainThread());
        taskQueue.enqueueTask([&]() {
            EXPECT_TRUE(isMainThread());
            currentStep++;
            EXPECT_EQ(1, currentStep);
        });
        taskQueue.enqueueTask([&]() {
            EXPECT_TRUE(isMainThread());
            currentStep++;
            EXPECT_EQ(2, currentStep);
            testFinished = true;
        });
    };
    RunLoop::current().dispatch([backgroundThreadFunction = WTFMove(backgroundThreadFunction)]() mutable {
        WTF::Thread::create("atq-background", WTFMove(backgroundThreadFunction))->detach();
    });

    Util::run(&testFinished);
}

struct FancyResponse {
    WTF_MAKE_NONCOPYABLE(FancyResponse);
public:
    FancyResponse(int fancyInt, bool* destructedFlagPointer = nullptr)
        : fancyInt(fancyInt)
        , destructedFlagPointer(destructedFlagPointer)
    { }

    FancyResponse(FancyResponse&& original)
        : fancyInt(original.fancyInt)
        , destructedFlagPointer(original.destructedFlagPointer)
    {
        original.destructedFlagPointer = nullptr;
    }

    ~FancyResponse()
    {
        if (destructedFlagPointer) {
            RELEASE_ASSERT(!*destructedFlagPointer);
            *destructedFlagPointer = true;
        }
    }

    FancyResponse& operator=(FancyResponse&& a)
    {
        this->fancyInt = a.fancyInt;
        return *this;
    }

    int fancyInt;
    bool* destructedFlagPointer;
};

TEST(AbortableTaskQueue, SyncTasks)
{
    AbortableTaskQueue taskQueue;
    bool testFinished { false };
    bool destructedResponseFlag { false };
    int currentStep { 0 };
    WTF::initializeMainThread();

    auto backgroundThreadFunction = [&]() {
        EXPECT_FALSE(isMainThread());
        std::optional<FancyResponse> response = taskQueue.enqueueTaskAndWait<FancyResponse>([&]() -> FancyResponse {
            EXPECT_TRUE(isMainThread());
            currentStep++;
            EXPECT_EQ(1, currentStep);
            FancyResponse returnValue(100, &destructedResponseFlag);
            return returnValue;
        });
        currentStep++;
        EXPECT_EQ(2, currentStep);
        EXPECT_TRUE(response);
        EXPECT_FALSE(destructedResponseFlag);
        EXPECT_EQ(100, response->fancyInt);
        response = std::nullopt;
        EXPECT_TRUE(destructedResponseFlag);
        RunLoop::main().dispatch([&]() {
            testFinished = true;
        });
    };
    RunLoop::current().dispatch([backgroundThreadFunction = WTFMove(backgroundThreadFunction)]() mutable {
        WTF::Thread::create("atq-background", WTFMove(backgroundThreadFunction))->detach();
    });

    Util::run(&testFinished);
}

template <typename ThreadEnum>
class DeterministicScheduler {
    WTF_MAKE_NONCOPYABLE(DeterministicScheduler);
public:
    DeterministicScheduler(ThreadEnum firstThread)
        : m_currentThread(firstThread)
    { }

    class ThreadContext {
        WTF_MAKE_NONCOPYABLE(ThreadContext);
    public:
        ThreadContext(DeterministicScheduler& scheduler, ThreadEnum thisThread)
            : m_scheduler(scheduler), m_thisThread(thisThread)
        { }

        void waitMyTurn()
        {
            Locker locker { m_scheduler.m_mutex };
            m_scheduler.m_currentThreadChanged.wait(m_scheduler.m_mutex, [this]() {
                return m_scheduler.m_currentThread == m_thisThread;
            });
        }

        void yieldToThread(ThreadEnum nextThread)
        {
            Locker locker { m_scheduler.m_mutex };
            m_scheduler.m_currentThread = nextThread;
            m_scheduler.m_currentThreadChanged.notifyAll();
        }

    private:
        DeterministicScheduler& m_scheduler;
        ThreadEnum m_thisThread;
    };


private:
    ThreadEnum m_currentThread;
    Condition m_currentThreadChanged;
    Lock m_mutex;
};

enum class TestThread {
    Main,
    Background
};

TEST(AbortableTaskQueue, Abort)
{
    DeterministicScheduler<TestThread> scheduler(TestThread::Background);

    AbortableTaskQueue taskQueue;
    bool testFinished { false };
    WTF::initializeMainThread();

    auto backgroundThreadFunction = [&]() {
        EXPECT_FALSE(isMainThread());
        DeterministicScheduler<TestThread>::ThreadContext backgroundThreadContext(scheduler, TestThread::Background);

        taskQueue.enqueueTask([]() {
            // This task should not have been able to run under the scheduling of this test.
            EXPECT_TRUE(false);
        });
        backgroundThreadContext.yieldToThread(TestThread::Main);
        backgroundThreadContext.waitMyTurn();

        // Main thread has called startAborting().

        taskQueue.enqueueTask([]() {
            // This task should not have been able to run under the scheduling of this test.
            EXPECT_TRUE(false);
        });
        // This call must return immediately because we are aborting.
        std::optional<FancyResponse> response = taskQueue.enqueueTaskAndWait<FancyResponse>([]() -> FancyResponse {
            // This task should not have been able to run under the scheduling of this test.
            EXPECT_TRUE(false);
            return FancyResponse(100);
        });
        EXPECT_FALSE(response);
        backgroundThreadContext.yieldToThread(TestThread::Main);
        backgroundThreadContext.waitMyTurn();

        // Main thread has called finishAborting().

        taskQueue.enqueueTask([&]() {
            testFinished = true;
        });
    };
    RunLoop::current().dispatch([&, backgroundThreadFunction = WTFMove(backgroundThreadFunction)]() mutable {
        EXPECT_TRUE(isMainThread());
        DeterministicScheduler<TestThread>::ThreadContext mainThreadContext(scheduler, TestThread::Main);
        WTF::Thread::create("atq-background", WTFMove(backgroundThreadFunction))->detach();

        mainThreadContext.waitMyTurn();

        taskQueue.startAborting();
        mainThreadContext.yieldToThread(TestThread::Background);
        mainThreadContext.waitMyTurn();

        taskQueue.finishAborting();
        mainThreadContext.yieldToThread(TestThread::Background);
    });

    Util::run(&testFinished);
}

TEST(AbortableTaskQueue, AbortBeforeSyncTaskRun)
{
    AbortableTaskQueue taskQueue;
    bool testFinished { false };
    WTF::initializeMainThread();

    auto backgroundThreadFunction = [&]() {
        EXPECT_FALSE(isMainThread());

        std::optional<FancyResponse> response = taskQueue.enqueueTaskAndWait<FancyResponse>([]() -> FancyResponse {
            // This task should not have been able to run under the scheduling of this test.
            EXPECT_TRUE(false);
            return FancyResponse(100);
        });

        // Main thread has called startAborting().
        EXPECT_FALSE(response);

        RunLoop::main().dispatch([&]() {
            testFinished = true;
        });
    };
    RunLoop::current().dispatch([&, backgroundThreadFunction = WTFMove(backgroundThreadFunction)]() mutable {
        EXPECT_TRUE(isMainThread());
        WTF::Thread::create("atq-background", WTFMove(backgroundThreadFunction))->detach();

        // Give the background thread a bit of time to get blocked waiting for a response.
        WTF::sleep(100_ms);

        taskQueue.startAborting();
    });

    Util::run(&testFinished);
}

TEST(AbortableTaskQueue, AbortedBySyncTaskHandler)
{
    AbortableTaskQueue taskQueue;
    bool testFinished { false };
    int currentStep { 0 };
    bool destructedResponseFlag { false };
    WTF::initializeMainThread();

    auto backgroundThreadFunction = [&]() {
        EXPECT_FALSE(isMainThread());
        currentStep++;
        EXPECT_EQ(1, currentStep);

        std::optional<FancyResponse> response = taskQueue.enqueueTaskAndWait<FancyResponse>([&]() -> FancyResponse {
            currentStep++;
            EXPECT_EQ(2, currentStep);
            taskQueue.startAborting();
            // This task should not have been able to run under the scheduling of this test.
            return FancyResponse(100, &destructedResponseFlag);
        });

        currentStep++;
        EXPECT_EQ(3, currentStep);

        // Main thread has called startAborting().
        EXPECT_FALSE(response);

        // The response object has not been leaked.
        EXPECT_TRUE(destructedResponseFlag);

        RunLoop::main().dispatch([&]() {
            testFinished = true;
        });
    };
    RunLoop::current().dispatch([&, backgroundThreadFunction = WTFMove(backgroundThreadFunction)]() mutable {
        EXPECT_TRUE(isMainThread());
        WTF::Thread::create("atq-background", WTFMove(backgroundThreadFunction))->detach();
    });

    Util::run(&testFinished);
}

} // namespace TestWebKitAPI
