/*
 * Copyright (C) 2023 Apple Inc. All rights reserved.
 *
 * Portions are Copyright (C) 2017-2021 Mozilla Corporation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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 <wtf/NativePromise.h>

#include "Helpers/Test.h"
#include "Helpers/Utilities.h"
#include <wtf/Atomics.h>
#include <wtf/Lock.h>
#include <wtf/Locker.h>
#include <wtf/Ref.h>
#include <wtf/RefCountedFixedVector.h>
#include <wtf/RefPtr.h>
#include <wtf/RunLoop.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/WorkQueue.h>
#include <wtf/threads/BinarySemaphore.h>

using namespace WTF;

namespace TestWebKitAPI {

using TestPromise = NativePromise<int, double, PromiseOption::Default | PromiseOption::NonExclusive>;
using TestPromiseExcl = NativePromise<int, double>;

class WorkQueueWithShutdown : public WorkQueue {
public:
    static Ref<WorkQueueWithShutdown> create(ASCIILiteral name) { return adoptRef(*new WorkQueueWithShutdown(name)); }
    void beginShutdown()
    {
        dispatch([this, strong = Ref { *this }] {
            m_shutdown = true;
            m_semaphore.signal();
        });
    }
    void waitUntilShutdown()
    {
        while (!m_shutdown)
            m_semaphore.wait();
    }

private:
    WorkQueueWithShutdown(ASCIILiteral name)
        : WorkQueue(name, QOS::Default)
    {
    }
    std::atomic<bool> m_shutdown { false };
    BinarySemaphore m_semaphore;
};

class AutoWorkQueue {
public:
    AutoWorkQueue()
        : m_workQueue(WorkQueueWithShutdown::create("com.apple.WebKit.Test.simple"_s))
    {
    }

    Ref<WorkQueueWithShutdown> queue() { return m_workQueue; }

    ~AutoWorkQueue()
    {
        m_workQueue->waitUntilShutdown();
    }

private:
    Ref<WorkQueueWithShutdown> m_workQueue;
};

struct RefCountedProducer final : public ThreadSafeRefCounted<RefCountedProducer> {
    Ref<TestPromise> promise() { return producer; }
    typename TestPromise::Producer producer;
};

class DelayedSettle final : public ThreadSafeRefCounted<DelayedSettle> {
public:
    DelayedSettle(WorkQueue& workQueue, RefPtr<RefCountedProducer> producer, TestPromise::Result&& result, int iterations)
        : m_producer(producer)
        , m_iterations(iterations)
        , m_workQueue(workQueue)
        , m_result(WTF::move(result))
    {
    }

    void dispatch()
    {
        m_workQueue->dispatch([protectedThis = RefPtr { this }] {
            protectedThis->run();
        });
    }

    void run()
    {
        assertIsCurrent(m_workQueue);

        Locker lock { m_lock };
        if (!m_producer) {
            // Canceled.
            return;
        }

        if (!--m_iterations) {
            m_producer->producer.settle(m_result);
            return;
        }

        dispatch();
    }

    void cancel()
    {
        Locker lock { m_lock };
        m_producer = nullptr;
    }

private:
    Lock m_lock;
    RefPtr<RefCountedProducer> m_producer WTF_GUARDED_BY_LOCK(m_lock);
    int m_iterations WTF_GUARDED_BY_LOCK(m_lock);
    Ref<WorkQueue> m_workQueue;
    const TestPromise::Result m_result;
};

static auto doFail()
{
    return [] {
        EXPECT_TRUE(false);
    };
}

static auto doFailAndReject(Logger::LogSiteIdentifier location = Logger::LogSiteIdentifier(__builtin_FUNCTION(), 0))
{
    return [location = WTF::move(location)] {
        EXPECT_TRUE(false);
        return TestPromise::createAndReject(0.0, location);
    };
}

static void runInCurrentRunLoop(Function<void(RunLoop&)>&& function)
{
    WTF::initializeMainThread();
    auto& runLoop = RunLoop::currentSingleton();

    function(runLoop);

    bool done = false;
    runLoop.dispatch([&] {
        done = true;
    });
    while (!done)
        runLoop.cycle();
}

static void runInCurrentRunLoopUntilDone(Function<void(RunLoop&, bool&)>&& function)
{
    WTF::initializeMainThread();
    auto& runLoop = RunLoop::currentSingleton();

    bool done = false;

    function(runLoop, done);

    while (!done)
        runLoop.cycle();
}

// Basis usage, create a resolved promise, then on a different workqueue.
TEST(NativePromise, BasicResolve)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        TestPromise::createAndResolve(42)->then(queue,
            [queue](int resolveValue) {
                EXPECT_EQ(resolveValue, 42);
                queue->beginShutdown();
            }, doFail());
    });
}

// Basis usage, create a rejected promise, then on a different workqueue.
TEST(NativePromise, BasicReject)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        TestPromise::createAndReject(42.0)->then(queue,
            doFail(),
            [queue](int rejectValue) {
                EXPECT_EQ(rejectValue, 42.0);
                queue->beginShutdown();
            });
    });
}

// Basis usage, create a resolved promise, whenSettled on a different workqueue.
TEST(NativePromise, BasicSettleResolved)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        TestPromise::createAndResolve(42)->whenSettled(queue,
            [queue](const TestPromise::Result& result) {
                EXPECT_TRUE(result);
                EXPECT_EQ(result.value(), 42);
                queue->beginShutdown();
            });
    });
}

// Basis usage, create a rejected promise, whenSettled on a different workqueue.
TEST(NativePromise, BasicSettleRejected)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        TestPromise::createAndReject(42.0)->whenSettled(queue,
            [queue](const TestPromise::Result& result) {
                EXPECT_TRUE(!result);
                EXPECT_EQ(result.error(), 42.0);
                queue->beginShutdown();
            });
    });
}

// Example use with a GenericPromise which is a NativePromise<void, void>
//
TEST(NativePromise, GenericPromise)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        GenericPromise::createAndResolve()->then(queue,
            []() {
                EXPECT_TRUE(true);
            },
            doFail());

        GenericPromise::createAndResolve()->whenSettled(queue,
            [](GenericPromise::Result result) {
                EXPECT_TRUE(result);
            });

        GenericPromise::createAndReject()->whenSettled(queue,
            [](GenericPromise::Result result) {
                EXPECT_TRUE(!result);
            });

        GenericPromise::Producer producer1;
        // A producer is directly convertible into the promise it can settle.
        Ref<GenericPromise> promise1 = producer1;
        producer1.resolve();
        promise1->then(queue,
            []() {
                EXPECT_TRUE(true);
            },
            doFail());

        GenericPromise::Producer producer2;
        Ref<GenericPromise> promise2 = producer2;
        producer2.reject();
        promise2->then(queue,
            doFail(),
            []() {
                EXPECT_TRUE(true);
            });

        GenericPromise::Producer producer3;
        Ref<GenericPromise> promise3 = producer3;
        auto request3 = NativePromiseRequest::create();

        // Note that if you're not interested in the result you can provide two Function<void()> to then()
        promise3->then(queue, doFail(), doFail()).track(request3.get());
        producer3.resolve();

        // We are no longer interested by the result of the promise. We disconnect the request holder.
        // doFail() above will never be called.
        request3->disconnect();

        // Note that if you're not interested in the result you can also provide one Function<void()> with whenSettled()
        GenericPromise::Producer producer4;
        Ref<GenericPromise> promise4 = producer4;

        promise4->whenSettled(queue, []() {
        });
        producer4.resolve();

        // You can mix & match promise types and chain them together.
        // Producer also accepts syntax using operator-> for consistency with a consumer's promise.
        GenericPromise::Producer producer5;
        using MyPromise = NativePromise<int, int>;
        producer5->whenSettled(queue,
            [](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
                return MyPromise::createAndResolve(1);
            })->whenSettled(queue,
                [queue](MyPromise::Result result) {
                    static_assert(std::is_same_v<MyPromise::Result::value_type, int>, "The type received is the same as the last promise returned");
                    EXPECT_TRUE(result.has_value());
                    EXPECT_EQ(result.value(), 1);
                    queue->beginShutdown();
                });
        producer5->resolve();
    });
}

TEST(NativePromise, CallbacksWithAuto)
{
    using MyPromiseNonExclusive = NativePromise<bool, bool, PromiseOption::Default | PromiseOption::NonExclusive>;
    runInCurrentRunLoop([&](auto& runLoop) {
        MyPromiseNonExclusive::Producer producer;
        Ref<MyPromiseNonExclusive> promise = producer;
        promise->then(runLoop, [] (auto val) {
            EXPECT_TRUE(val);
        }, [] (auto val) {
            EXPECT_TRUE(val);
        });
        promise->then(runLoop, [] (bool val) {
            EXPECT_TRUE(val);
        }, [] (auto val) {
            EXPECT_TRUE(val);
        });
        promise->then(runLoop, [] (auto val) {
            EXPECT_TRUE(val);
        }, [] (bool val) {
            EXPECT_TRUE(val);
        });
        promise->then(runLoop, [] {
            EXPECT_TRUE(true);
        }, [] (auto val) {
            EXPECT_TRUE(val);
        });
        promise->then(runLoop, [] (auto val) {
            EXPECT_TRUE(val);
        }, [] {
            EXPECT_TRUE(true);
        });
        promise->whenSettled(runLoop, [] (auto val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        promise->whenSettled(runLoop, [] (const auto val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        promise->whenSettled(runLoop, [] (const auto& val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        promise->whenSettled(runLoop, [] (const MyPromiseNonExclusive::Result& val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        promise->whenSettled(runLoop, [] (MyPromiseNonExclusive::Result val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        promise->whenSettled(runLoop, [] {
        });
        producer.resolve(true);
    });

    using MyPromise = NativePromise<bool, bool>;
    runInCurrentRunLoop([&](auto& runLoop) {
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] (auto&& val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] (auto val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] (const auto val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] (const auto& val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] (MyPromise::Result&& val) {
            EXPECT_TRUE(val);
            EXPECT_TRUE(val.value());
        });
        MyPromise::createAndResolve(true)->whenSettled(runLoop, [] () {
            EXPECT_TRUE(true);
        });
    });
}

TEST(NativePromise, PromiseRequest)
{
    // We declare the Request holder before using the runLoop to ensure it stays in scope for the entire run.
    // ASSERTION FAILED: !m_request
    using MyPromise = NativePromise<bool, bool>;
    auto request1 = NativePromiseRequest::create();

    runInCurrentRunLoop([&](auto& runLoop) {
        MyPromise::Producer producer1;
        Ref<MyPromise> promise1 = producer1;
        producer1.resolve(true);

        promise1->whenSettled(runLoop,
            [&](MyPromise::Result&& result) {
                EXPECT_TRUE(result.has_value());
                EXPECT_TRUE(result.value());
                EXPECT_TRUE(request1->hasCallback());
                request1->complete();
                EXPECT_FALSE(request1->hasCallback());
            }).track(request1.get());
    });

    // PromiseRequest allows to use capture by reference or pointer to ref-counted object and ensure the
    // lifetime of the object.
    bool objectToShare = true;
    runInCurrentRunLoop([&](auto& runLoop) {
        auto request2 = NativePromiseRequest::create();
        GenericPromise::Producer producer2;
        Ref<GenericPromise> promise2 = producer2;
        promise2->whenSettled(runLoop,
            [&objectToShare](GenericPromise::Result&&) mutable {
                // It would be normally unsafe to access `objectToShare` as it went out of scope.
                // but this function will never run as we've disconnected the ThenCommand.
                objectToShare = false;
            }).track(request2.get());
        EXPECT_TRUE(request2->hasCallback());
        request2->disconnect();
        EXPECT_FALSE(request2->hasCallback());
        producer2.resolve();
        EXPECT_TRUE(objectToShare);
    });
    EXPECT_TRUE(objectToShare);
}

// Ensure that callbacks aren't run when request holder is disconnected after the promise was resolved and then() called.
TEST(NativePromise, PromiseRequestDisconnected1)
{
    runInCurrentRunLoop([](auto& runLoop) {
        auto request = NativePromiseRequest::create();

        TestPromise::Producer producer;
        Ref<TestPromise> promise = producer;
        promise->then(runLoop, doFail(), doFail()).track(request.get());

        producer.resolve(1);
        request->disconnect();
    });
}

// Ensure that callbacks aren't run when request holder is disconnected even if promise was resolved first.
TEST(NativePromise, PromiseRequestDisconnected2)
{
    runInCurrentRunLoop([](auto& runLoop) {
        auto request = NativePromiseRequest::create();

        TestPromise::Producer producer;
        Ref<TestPromise> promise = producer;
        producer.resolve(1);

        promise->then(runLoop, doFail(), doFail())->track(request.get());

        request->disconnect();
    });
}

TEST(NativePromise, AsyncResolve)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        RefPtr producer = adoptRef(new RefCountedProducer());
        auto promise = producer->promise();

        // Kick off three racing tasks, and make sure we get the one that finishes
        // earliest.
        Ref delayedSettleTask1 = adoptRef(*new DelayedSettle(queue, producer, TestPromise::Result(32), 10));
        Ref delayedSettleTask2 = adoptRef(*new DelayedSettle(queue, producer, TestPromise::Result(42), 5));
        Ref delayedSettleTask3 = adoptRef(*new DelayedSettle(queue, producer, TestPromise::Error(32.0), 7));

        delayedSettleTask1->dispatch();
        delayedSettleTask2->dispatch();
        delayedSettleTask3->dispatch();

        promise->then(queue,
            [queue, delayedSettleTask1, delayedSettleTask2, delayedSettleTask3](int resolveValue) {
                EXPECT_EQ(resolveValue, 42);
                delayedSettleTask1->cancel();
                delayedSettleTask2->cancel();
                delayedSettleTask3->cancel();
                queue->beginShutdown();
            },
            doFail());
    });
}

TEST(NativePromise, CompletionPromises)
{
    bool invokedPass { false }; // Only ever accessed on the WorkQueue
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue, &invokedPass] {
        TestPromise::createAndResolve(40)->then(queue,
            [](int val) {
                return TestPromise::createAndResolve(val + 10);
            },
            doFailAndReject())->then(queue,
                [&invokedPass](int val) {
                    invokedPass = true;
                    return TestPromise::createAndResolve(val);
                },
                doFailAndReject())->then(queue,
                    [queue](int val) {
                        RefPtr producer = adoptRef(new RefCountedProducer());
                        auto p = producer->promise();

                        Ref resolver = adoptRef(*new DelayedSettle(queue, producer, TestPromise::Result(val - 8), 10));
                        resolver->dispatch();
                        return p;
                    },
                    doFailAndReject())->then(queue,
                        [](int val) {
                            return TestPromise::createAndReject(double(val - 42) + 42.0);
                        },
                        doFailAndReject())->then(queue,
                            doFail(),
                            [queue, &invokedPass](double val) {
                                EXPECT_EQ(val, 42.0);
                                EXPECT_TRUE((bool)invokedPass);
                                queue->beginShutdown();
                            });
    });
}

TEST(NativePromise, UsingMethods)
{
    class MyClass : public ThreadSafeRefCounted<MyClass> {
    public:
        static Ref<MyClass> create() { return adoptRef(*new MyClass()); }
        void resolveWithNothing()
        {
            EXPECT_TRUE(true);
        }
        void rejectWithNothing()
        {
            EXPECT_TRUE(false);
        }
        void resolveWithValue(int value)
        {
            EXPECT_EQ(value, 1);
        }
        void rejectWithValue(double value)
        {
            EXPECT_EQ(value, 2.0);
        }
        void settleWithNothing()
        {
            EXPECT_TRUE(true);
        }
        void settleWithResult(const TestPromise::Result& result)
        {
            EXPECT_TRUE(result.has_value());
            EXPECT_EQ(result.value(), 1);
        }
    };
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue, myClass = MyClass::create()] {
        TestPromise::createAndResolve(1)->then(queue, myClass.get(), &MyClass::resolveWithNothing, &MyClass::rejectWithNothing);
        TestPromise::createAndReject(2.0)->then(queue, myClass.get(), &MyClass::resolveWithValue, &MyClass::rejectWithValue);
        TestPromise::createAndResolve(3)->whenSettled(queue, myClass.get(), &MyClass::settleWithNothing);
        TestPromise::createAndResolve(1)->whenSettled(queue, myClass.get(), &MyClass::settleWithResult);
        queue->dispatch([queue] {
            queue->beginShutdown();
        });
    });
}

static Ref<GenericPromise> myMethod()
{
    assertIsCurrent(RunLoop::mainSingleton());
    // You would normally do some work here.
    return GenericPromise::createAndResolve();
}

TEST(NativePromise, InvokeAsync)
{
    bool done = false;
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue, &done] {
        invokeAsync(RunLoop::mainSingleton(), &myMethod)->whenSettled(queue,
            [queue, &done](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
                queue->beginShutdown();
                done = true;
            });
    });

    Util::run(&done);
}

// A chained promise (that is promise->whenSettled([] { return GenericPromise }) is itself a promise
static Ref<GenericPromise> myMethodReturningThenCommandWithPromise()
{
    assertIsCurrent(RunLoop::mainSingleton());
    // You would normally do some work here.
    return GenericPromise::createAndResolve()->whenSettled(RunLoop::mainSingleton(),
        [](GenericPromise::Result result) {
            return GenericPromise::createAndSettle(WTF::move(result));
        });
}

static Ref<GenericPromise> myMethodReturningThenCommandWithVoid()
{
    assertIsCurrent(RunLoop::mainSingleton());
    // You would normally do some work here.
    return GenericPromise::createAndReject()->whenSettled(RunLoop::mainSingleton(),
        [](GenericPromise::Result result) {
            EXPECT_FALSE(result.has_value());
        });
}

TEST(NativePromise, InvokeAsyncAutoConversion)
{
    // Ensure that there's no need to cast NativePromise::then() result
    bool done = false;
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        invokeAsync(RunLoop::mainSingleton(), &myMethodReturningThenCommandWithPromise)->whenSettled(queue,
            [](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
            });
    });
    queue->dispatch([queue, &done] {
        invokeAsync(RunLoop::mainSingleton(), &myMethodReturningThenCommandWithVoid)->whenSettled(queue,
            [queue, &done](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
                queue->beginShutdown();
                done = true;
            });
    });

    Util::run(&done);
}

TEST(NativePromise, InvokeAsyncWithExpected)
{
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {
        auto asyncMethodWithExpected = [] {
            return std::expected<int, long> { 1 };
        };

        invokeAsync(runLoop, WTF::move(asyncMethodWithExpected))->whenSettled(runLoop, [&](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(result.value(), 1L);
            done = true;
        });
    });
}

TEST(NativePromise, InvokeAsyncWithVoid)
{
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {
        invokeAsync(runLoop, [] {
            EXPECT_TRUE(true);
        })->whenSettled(runLoop, [&](auto&& result) {
            EXPECT_TRUE(!!result);
            static_assert(std::is_same_v<std::remove_reference_t<decltype(result)>, GenericPromise::Result>, "We must be getting a GenericPromise");
            static_assert(std::is_void_v<typename std::remove_reference_t<decltype(result)>::value_type>);
            done = true;
        });
    });
}

static Ref<GenericPromise> myMethodReturningProducer()
{
    assertIsCurrent(RunLoop::mainSingleton());
    // You would normally do some work here.
    return GenericPromise::createAndResolve()->whenSettled(RunLoop::mainSingleton(),
        [](GenericPromise::Result result) {
            GenericPromise::Producer producer;
            producer.settle(WTF::move(result));
            return producer;
        });
}

TEST(NativePromise, InvokeAsyncAutoConversionWithProducer)
{
    // Ensure that there's no need to cast NativePromise::whenSettled() result
    bool done = false;
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue, &done] {
        invokeAsync(RunLoop::mainSingleton(), &myMethodReturningProducer)->whenSettled(queue,
            [queue, &done](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
                queue->beginShutdown();
                done = true;
            });
    });

    Util::run(&done);
}

TEST(NativePromise, PromiseAllResolve)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(TestPromise::createAndResolve(22));
        promises.append(TestPromise::createAndResolve(32));
        promises.append(TestPromise::createAndResolve(42));

        TestPromise::all(promises)->then(queue,
            [queue](const Vector<int>& resolveValues) {
                EXPECT_EQ(resolveValues.size(), 3UL);
                EXPECT_EQ(resolveValues[0], 22);
                EXPECT_EQ(resolveValues[1], 32);
                EXPECT_EQ(resolveValues[2], 42);
                queue->beginShutdown();
            },
            doFail());
    });
}

TEST(NativePromise, PromiseVoidAllResolve)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<GenericPromise>> promises;
        promises.append(GenericPromise::createAndResolve());
        promises.append(GenericPromise::createAndResolve());
        promises.append(GenericPromise::createAndResolve());

        GenericPromise::all(promises)->then(queue,
            [] () {
                EXPECT_TRUE(true);
            },
            doFail());

        GenericPromise::all(Vector<Ref<GenericPromise>>(10, [](size_t) {
            return GenericPromise::createAndResolve();
        }))->then(queue,
            [queue] () {
                queue->beginShutdown();
            },
            doFail());
    });
}

TEST(NativePromise, PromiseAllResolveAsync)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(22);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(32);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(42);
        }));

        TestPromise::all(promises)->then(queue,
            [queue](const Vector<int>& resolveValues) {
                EXPECT_EQ(resolveValues.size(), 3UL);
                EXPECT_EQ(resolveValues[0], 22);
                EXPECT_EQ(resolveValues[1], 32);
                EXPECT_EQ(resolveValues[2], 42);
                queue->beginShutdown();
            },
            doFail());
    });
}

TEST(NativePromise, PromiseAllReject)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(TestPromise::createAndResolve(22));
        promises.append(TestPromise::createAndReject(32.0));
        promises.append(TestPromise::createAndResolve(42));
        // Ensure that more than one rejection doesn't cause a crash
        promises.append(TestPromise::createAndReject(52.0));

        TestPromise::all(promises)->then(queue,
            doFail(),
            [queue](float rejectValue) {
                EXPECT_EQ(rejectValue, 32.0);
                queue->beginShutdown();
            });
    });
}

TEST(NativePromise, PromiseAllRejectAsync)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(22);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndReject(32.0);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(42);
        }));
        // Ensure that more than one rejection doesn't cause a crash
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndReject(52.0);
        }));

        TestPromise::all(promises)->then(queue,
            doFail(),
            [queue](float rejectValue) {
                EXPECT_EQ(rejectValue, 32.0);
                queue->beginShutdown();
            });
    });
}

TEST(NativePromise, PromiseAllSettled)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(TestPromise::createAndResolve(22));
        promises.append(TestPromise::createAndReject(32.0));
        promises.append(TestPromise::createAndResolve(42));
        promises.append(TestPromise::createAndReject(52.0));

        TestPromise::allSettled(promises)->then(
            queue,
            [queue](const TestPromise::AllSettledPromiseType::ResolveValueType& resolveValues) {
                EXPECT_EQ(resolveValues.size(), 4UL);
                EXPECT_TRUE(resolveValues[0]);
                EXPECT_EQ(resolveValues[0].value(), 22);
                EXPECT_FALSE(resolveValues[1]);
                EXPECT_EQ(resolveValues[1].error(), 32.0);
                EXPECT_TRUE(resolveValues[2]);
                EXPECT_EQ(resolveValues[2].value(), 42);
                EXPECT_FALSE(resolveValues[3]);
                EXPECT_EQ(resolveValues[3].error(), 52.0);
                queue->beginShutdown();
            },
            doFail());
    });
}

TEST(NativePromise, PromiseAllSettledAsync)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();

    queue->dispatch([queue] {
        Vector<Ref<TestPromise>> promises;
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(22);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndReject(32.0);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndResolve(42);
        }));
        promises.append(invokeAsync(queue, [] {
            return TestPromise::createAndReject(52.0);
        }));

        TestPromise::allSettled(promises)->then(queue,
            [queue](const TestPromise::AllSettledPromiseType::ResolveValueType& resolveValues) {
                EXPECT_EQ(resolveValues.size(), 4UL);
                EXPECT_TRUE(resolveValues[0].has_value());
                EXPECT_EQ(resolveValues[0].value(), 22);
                EXPECT_FALSE(resolveValues[1].has_value());
                EXPECT_EQ(resolveValues[1].error(), 32.0);
                EXPECT_TRUE(resolveValues[2].has_value());
                EXPECT_EQ(resolveValues[2], 42);
                EXPECT_FALSE(resolveValues[3].has_value());
                EXPECT_EQ(resolveValues[3].error(), 52.0);
                queue->beginShutdown();
            },
            doFail());
    });
}

// Chain 100 promises, and disconnect the chain after the 50th resolve.
TEST(NativePromise, Chaining)
{
    // We declare this variable before |awq| to ensure the destructor is run after |holder.disconnect()|.
    auto holder = NativePromiseRequest::create();

    AutoWorkQueue awq;
    auto queue = awq.queue();

    queue->dispatch([queue, &holder] {
        auto promise = TestPromise::createAndResolve(42);
        const size_t kIterations = 100;
        for (size_t i = 0; i < kIterations; ++i) {
            promise = promise->then(queue,
                [](int val) {
                    EXPECT_EQ(val, 42);
                    return TestPromise::createAndResolve(val);
                },
                [](double val) {
                    return TestPromise::createAndReject(val);
                });

            if (i == kIterations / 2) {
                promise->then(queue,
                    [queue, &holder] {
                        holder->disconnect();
                        queue->beginShutdown();
                    },
                    doFail());
            }
        }
        // We will hit the assertion if we don't disconnect the leaf Request
        // in the promise chain.
        promise->whenSettled(queue, [] { })->track(holder.get());
    });
}

TEST(NativePromise, MoveOnlyType)
{
    using MyPromise = NativePromise<std::unique_ptr<int>, std::unique_ptr<int>>;

    AutoWorkQueue awq;
    auto queue = awq.queue();

    MyPromise::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(87))->then(queue,
        [](std::unique_ptr<int> val) {
            EXPECT_EQ(87, *val);
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(87))->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_EQ(87, *(*val));
        });

    MyPromise::createAndReject(makeUniqueWithoutFastMallocCheck<int>(87))->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_FALSE(val.has_value());
            EXPECT_EQ(87, *(val.error()));
            queue->beginShutdown();
        });
}

// A WTFString can be directly returned by a producer. More generically, so long as an object implements an `isolatedCopy()` method, it will be automatically called.
TEST(NativePromise, WTFString)
{
    using MyPromise = NativePromise<String, String>;

    AutoWorkQueue awq2;
    auto queue2 = awq2.queue();

    AutoWorkQueue awq;
    auto queue = awq.queue();

    MyPromise::createAndResolve("hello"_s)->then(queue,
        [](String&& val) {
            EXPECT_EQ(String("hello"_s), val);
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve("hello"_s)->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_EQ(String("hello"_s), val.value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
        });

    MyPromise::createAndReject("error"_s)->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_FALSE(val.has_value());
            EXPECT_EQ(String("error"_s), val.error());
            EXPECT_TRUE(val.error().isSafeToSendToAnotherThread());
        });

    MyPromise::createAndResolve(String("hello"_s))->then(queue,
        [](String&& val) {
            EXPECT_EQ(String("hello"_s), val);
            EXPECT_TRUE(val.isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    // Check that we can receive the value by const reference too.
    MyPromise::createAndResolve(String("hello"_s))->then(queue,
        [](const String& val) {
            EXPECT_EQ(String("hello"_s), val);
            EXPECT_TRUE(val.isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    // Can pass object implecitly convertible to ResolveValueType
    MyPromise::createAndResolve(AtomString("hello"_s))->then(queue,
        [](String&& val) {
            EXPECT_EQ(String("hello"_s), val);
            EXPECT_TRUE(val.isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve(AtomString("hello"_s))->then(queue,
        [](const String& val) {
            EXPECT_EQ(String("hello"_s), val);
            EXPECT_TRUE(val.isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve(AtomString("hello"_s))->then(queue,
        [](String val) {
            EXPECT_EQ(String("hello"_s), val);
            EXPECT_TRUE(val.isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve(String("hello"_s))->whenSettled(queue,
        [](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("hello"_s), val.value());
        });

    MyPromise::createAndResolve(String("hello"_s))->whenSettled(queue,
        [](MyPromise::Result val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("hello"_s), val.value());
        });

    MyPromise::createAndResolve(String("hello"_s))->whenSettled(queue,
        [](const MyPromise::Result& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("hello"_s), val.value());
        });

    MyPromise::createAndReject(String("error"_s))->whenSettled(queue,
        [](MyPromise::Result&& val) {
            EXPECT_FALSE(val.has_value());
            EXPECT_TRUE(val.error().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("error"_s), val.error());
        });

    MyPromise::createAndResolve(AtomString("hello"_s))->whenSettled(queue,
        [](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("hello"_s), val.value());
            return MyPromise::createAndSettle(WTF::move(val));
        })->whenSettled(queue2,
            [](MyPromise::Result val) {
                EXPECT_TRUE(val.has_value());
                EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
                EXPECT_EQ(String("hello"_s), val.value());
            });

    MyPromise::createAndResolve(AtomString("hello"_s))->whenSettled(queue,
        [queue](MyPromise::Result val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("hello"_s), val.value());
            queue->beginShutdown();
            // Don't move the result to make sure we get a new isolatedCopy.
            return MyPromise::createAndSettle(val);
        })->whenSettled(queue2,
            [queue2](MyPromise::Result val) {
                EXPECT_TRUE(val.has_value());
                EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
                EXPECT_EQ(String("hello"_s), val.value());
                queue2->beginShutdown();
            });
}

TEST(NativePromise, WTFStringWithDelayedResolve)
{
    using MyPromise = NativePromise<String, String>;

    // The following steps runs strictly serially.
    // 1. We create a promise on the main thread.
    // 2. Dispatch a task that will `whenSettled()` on that promise on WorkQueue2.
    // 3. We resolve on the main thread the promise with an AtomString.
    // 4. Resolver will be called on WorkQueue1 and check that the string content is correct and the string created on the main thread was safely moved.

    AutoWorkQueue awq1;
    awq1.queue();
    auto queue1 = awq1.queue();
    MyPromise::Producer producer;
    bool hasRun = false; // AutoWorkQueue guarantees that there can't be concurrent accesses to hasRun.
    {
        AutoWorkQueue awq2;
        auto queue2 = awq2.queue();
        queue2->dispatch([queue1, queue2, promise = Ref<MyPromise> { producer }, &hasRun] {
            promise->whenSettled(queue1,
                [queue1](MyPromise::Result val) {
                    EXPECT_TRUE(val.has_value());
                    EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
                    EXPECT_EQ(String("hello"_s), val.value());
                    queue1->beginShutdown();
                });
            hasRun = true;
            queue2->beginShutdown();
        });
    }
    EXPECT_TRUE(hasRun);
    producer.resolve(AtomString("hello"_s));
}

TEST(NativePromise, NonExclusiveWithCrossThreadCopy)
{
    int resolution = 0;
    {
        AutoWorkQueue awq;
        auto queue = awq.queue();
        // If you replace PromiseOption::WithCrossThreadCopy with PromiseOption::WithoutCrossThreadCopy, this test will crash due to the AtomString being deleted on the target queue.
        using MyPromise = NativePromise<std::expected<String, AtomString>, bool, PromiseOption::NonExclusive | PromiseOption::WithCrossThreadCopy>;
        static_assert(CrossThreadCopier<std::expected<String, AtomString>>::IsNeeded);
        MyPromise::Producer producer;
        Ref<MyPromise> promise = producer;
        promise->whenSettled(queue, [&resolution] (const MyPromise::Result& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().has_value());
            EXPECT_TRUE(val.value().value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("that worked"_s), val.value().value());
            resolution++;
        });
        promise->whenSettled(queue, [&resolution] (MyPromise::Result val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().has_value());
            // Being a non-exclusive promise, the value is passed by const reference, so we copied the object in val.
            EXPECT_TRUE(!val.value().value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("that worked"_s), val.value().value());
            resolution++;
        });
        promise->whenSettled(queue, [queue, &resolution] (const MyPromise::Result& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_TRUE(val.value().has_value());
            // The previous whenSettled() has run already, and the object was derefed.
            EXPECT_TRUE(val.value().value().isSafeToSendToAnotherThread());
            EXPECT_EQ(String("that worked"_s), val.value().value());
            resolution++;
            queue->beginShutdown();
        });
        producer.resolve(String(AtomString("that worked"_s)));
    }
    EXPECT_EQ(3, resolution);
}

TEST(NativePromise, WithCrossThreadCopyType)
{
    using MyPromiseWithString = NativePromise<String, AtomString>;
    static_assert(MyPromiseWithString::WithAutomaticCrossThreadCopy);
    static_assert(CrossThreadCopier<typename MyPromiseWithString::RejectValueType>::IsNeeded);
    // Check that if making a NativePromise with an AtomString, you actually get a String
    static_assert(std::is_same_v<typename MyPromiseWithString::RejectValueType, String>);

    using MyPromiseWithoutString = NativePromise<int, bool>;
    static_assert(!MyPromiseWithoutString::WithAutomaticCrossThreadCopy);

    using MyPromiseWithArrayOfString = NativePromise<Vector<String>, bool>;
    static_assert(MyPromiseWithArrayOfString::WithAutomaticCrossThreadCopy);

    using MyNonExclusivePromise = NativePromise<Vector<int>, bool, PromiseOption::Default | PromiseOption::NonExclusive>;
    // No need for crossThreadProxy for a Vector not containing a type with isolatedCopy() method.
    static_assert(!MyNonExclusivePromise::WithAutomaticCrossThreadCopy);
}

TEST(NativePromise, ExpectedWithString)
{
    using MyPromise = NativePromise<std::expected<String, String>, int>;

    AutoWorkQueue awq;
    auto queue = awq.queue();

    MyPromise::createAndResolve(String("hello"_s))->then(queue,
        [](MyPromise::ResolveValueType&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_EQ(String("hello"_s), val.value());
            EXPECT_TRUE(val.value().isSafeToSendToAnotherThread());
        },
        [] {
            EXPECT_TRUE(false);
        });

    MyPromise::createAndResolve(String("hello"_s))->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_EQ(String("hello"_s), val.value());
            EXPECT_TRUE(val.value().value().isSafeToSendToAnotherThread());
        });

    std::expected<String, String> error = std::unexpected<String>("error"_s);
    MyPromise::createAndResolve(WTF::move(error))->whenSettled(queue,
        [queue](MyPromise::Result&& val) {
            EXPECT_TRUE(val.has_value());
            EXPECT_FALSE(val.value().has_value());
            EXPECT_EQ(String("error"_s), val.value().error());
            EXPECT_TRUE(val.value().error().isSafeToSendToAnotherThread());
            queue->beginShutdown();
        });
}

TEST(NativePromise, HeterogeneousChaining)
{
    using Promise1 = NativePromise<std::unique_ptr<char>, bool>;
    using Promise2 = NativePromise<std::unique_ptr<int>, bool>;

    auto holder = NativePromiseRequest::create();

    AutoWorkQueue awq;
    auto queue = awq.queue();

    queue->dispatch([queue, &holder] {
        Promise1::createAndResolve(makeUniqueWithoutFastMallocCheck<char>(0))->whenSettled(queue,
            [&holder] {
                holder->disconnect();
                return Promise2::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(0));
            })->whenSettled(queue,
                [] {
                    // Shouldn't be called for we've disconnected the request.
                    EXPECT_FALSE(true);
                })->track(holder.get());
    });

    Promise1::createAndResolve(makeUniqueWithoutFastMallocCheck<char>(87))->then(queue,
        [](std::unique_ptr<char> val) {
            EXPECT_EQ(87, *val);
            return Promise2::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(94));
        },
        [] {
            return Promise2::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(95));
        })->then(queue,
            [](std::unique_ptr<int> val) {
                EXPECT_EQ(94, *val);
            },
            doFail());

    Promise1::createAndResolve(makeUniqueWithoutFastMallocCheck<char>(87))->whenSettled(queue,
        [](Promise1::Result&& result) {
            EXPECT_EQ(87, *(result.value()));
            return Promise2::createAndResolve(makeUniqueWithoutFastMallocCheck<int>(94));
        })->whenSettled(queue,
            [queue](Promise2::Result&& result) {
                EXPECT_EQ(94, *(result.value()));
            });

    // Chaining promises of different types, even if returned from within callback
    TestPromise::createAndResolve(1)->whenSettled(queue,
        [queue] {
            return TestPromiseExcl::createAndResolve(2)->whenSettled(queue, [] {
                return TestPromise::createAndResolve(3);
            });
        })->whenSettled(queue,
            [queue](TestPromise::Result result) {
                EXPECT_TRUE(result.has_value());
                EXPECT_EQ(3, result.value());
            });

    TestPromise::createAndResolve(1)->whenSettled(queue,
        [queue] {
            return TestPromiseExcl::createAndResolve(2)->whenSettled(queue, [] {
                return GenericPromise::createAndResolve();
            });
        })->whenSettled(queue,
            [queue](GenericPromise::Result result) {
                EXPECT_TRUE(result.has_value());
            });

    TestPromise::createAndResolve(1)->whenSettled(queue,
        [queue] {
            return TestPromiseExcl::createAndResolve(2)->whenSettled(queue, [] {
                return GenericPromise::createAndReject();
            });
        })->whenSettled(queue,
            [queue](GenericPromise::Result result) {
                EXPECT_FALSE(result.has_value());
                queue->beginShutdown();
            });
}

TEST(NativePromise, RunLoop)
{
    runInCurrentRunLoop([](auto& runLoop) {
        TestPromise::createAndResolve(42)->then(runLoop,
            [](int resolveValue) {
                EXPECT_EQ(resolveValue, 42);
            },
            doFail());
    });
}

TEST(NativePromise, ImplicitConversionWithForwardPreviousReturn)
{
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {
        TestPromise::Producer producer;
        Ref<TestPromise> promise = producer;
        promise = promise->whenSettled(runLoop,
            [](const TestPromise::Result& result) {
                return TestPromise::createAndSettle(result);
            });
        promise->whenSettled(runLoop, [promise, &done](const TestPromise::Result& result) {
            EXPECT_TRUE(result.has_value());
            EXPECT_TRUE(promise->isResolved());
            done = true;
        });
        producer.resolve(1);
        Ref<TestPromise> originalPromise = producer;
        EXPECT_TRUE(originalPromise->isResolved());
        // This could be written as EXPECT_TRUE(static_cast<Ref<TestPromise>>(p)->isResolved());
        // but MSVC errors on it.
        EXPECT_FALSE(promise->isResolved()); // The callback hasn't been run yet.
    });
}

TEST(NativePromise, ChainTo)
{
    using VectorPromise = NativePromise<Ref<RefCountedFixedVector<int>>, bool, PromiseOption::Default | PromiseOption::NonExclusive>;
    auto resultVector = RefCountedFixedVector<int>::createFromVector(Vector<int>(FillWith { }, 5, 42));
    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer(), producer2 = VectorPromise::Producer()](auto& runLoop) mutable {
        auto promise = VectorPromise::createAndResolve(resultVector);
        producer1->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(resolveValue.get(), RefCountedFixedVector<int>::createFromVector(Vector<int>(FillWith { }, 5, 42)).get()); },
            doFail());
        producer2->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(resolveValue.get(), RefCountedFixedVector<int>::createFromVector(Vector<int>(FillWith { }, 5, 42)).get()); },
            doFail());

        // As promise1 is already resolved, it will automatically resolve/reject producer1 and producer2 with its resolved/reject value.
        promise->chainTo(WTF::move(producer1));
        promise->chainTo(WTF::move(producer2));
    });

    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer(), producer2 = VectorPromise::Producer()](auto& runLoop) mutable {
        producer2->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(resolveValue.get(), RefCountedFixedVector<int>::createFromVector(Vector<int>(FillWith { }, 5, 42)).get()); },
            doFail());

        // When producer1 is resolved, it will automatically settle producer2 with the resolved/reject value.
        producer1->chainTo(WTF::move(producer2));
        VectorPromise::createAndResolve(resultVector)->chainTo(WTF::move(producer1));
    });

    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer()](auto& runLoop) mutable {
        auto promise = VectorPromise::createAndResolve(resultVector);
        producer1->then(runLoop,
            [&](auto&& resolveValue) { EXPECT_EQ(resolveValue.get(), RefCountedFixedVector<int>::createFromVector(Vector<int>(FillWith { }, 5, 42)).get()); },
            doFail());

        // As promise1 is already resolved, it will automatically resolve/reject producer1 with its resolved/reject value.
        promise->chainTo(WTF::move(producer1));
    });
}

TEST(NativePromise, ChainToNonMovable)
{
    using VectorPromise = NativePromise<std::unique_ptr<Vector<int>>, bool, PromiseOption::Default | PromiseOption::NonExclusive>;
    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer(), producer2 = VectorPromise::Producer()](auto& runLoop) mutable {
        auto promise = VectorPromise::createAndResolve(makeUnique<Vector<int>>(FillWith { }, 5, 42));
        producer1->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(*resolveValue, Vector<int>(FillWith { }, 5, 42)); },
            doFail());
        producer2->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(*resolveValue, Vector<int>(FillWith { }, 5, 42)); },
            doFail());

        // As promise1 is already resolved, it will automatically resolve/reject producer1 and producer2 with its resolved/reject value.
        promise->chainTo(WTF::move(producer1));
        promise->chainTo(WTF::move(producer2));
    });

    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer(), producer2 = VectorPromise::Producer()](auto& runLoop) mutable {
        producer2->then(runLoop,
            [&](const auto& resolveValue) { EXPECT_EQ(*resolveValue, Vector<int>(FillWith { }, 5, 42)); },
            doFail());

        // When producer1 is resolved, it will automatically settle producer2 with the resolved/reject value.
        producer1->chainTo(WTF::move(producer2));
        VectorPromise::createAndResolve(makeUnique<Vector<int>>(FillWith { }, 5, 42))->chainTo(WTF::move(producer1));
    });

    runInCurrentRunLoop([&, producer1 = VectorPromise::Producer()](auto& runLoop) mutable {
        auto promise = VectorPromise::createAndResolve(makeUnique<Vector<int>>(FillWith { }, 5, 42));
        producer1->then(runLoop,
            [&](auto&& resolveValue) { EXPECT_EQ(*resolveValue, Vector<int>(FillWith { }, 5, 42)); },
            doFail());

        // As promise1 is already resolved, it will automatically resolve/reject producer1 with its resolved/reject value.
        promise->chainTo(WTF::move(producer1));
    });
}

TEST(NativePromise, RunSynchronouslyOnTarget)
{
    // Check that the callback is executed immediately when the promise is resolved.
    runInCurrentRunLoop([](auto& runLoop) {
        GenericPromise::Producer producer(PromiseDispatchMode::RunSynchronouslyOnTarget);
        int result = 0;
        producer.resolve();
        producer->whenSettled(runLoop, [&] {
            result = 42;
        });
        EXPECT_EQ(result, 42);
    });
    // Check that the callback is executed immediately when using chained promise and that itself is set to RunSynchronouslyOnTarget
    runInCurrentRunLoop([](auto& runLoop) {
        GenericPromise::Producer producer(PromiseDispatchMode::RunSynchronouslyOnTarget);
        int result = 0;
        producer->whenSettled(runLoop, [&] {
            // We need to configure this promise too as RunSynchronouslyOnTarget
            GenericPromise::Producer producer(PromiseDispatchMode::RunSynchronouslyOnTarget);
            producer.resolve();
            return producer;
        })->whenSettled(runLoop, [&] {
            result = 42;
        });
        producer.resolve();
        EXPECT_EQ(result, 42);
    });
    // Check that the callback will still run on the proper target queue, even if RunSynchronouslyOnTarget is set.
    runInCurrentRunLoop([](auto& runLoop) {
        GenericPromise::Producer producer(PromiseDispatchMode::RunSynchronouslyOnTarget);
        Ref<GenericPromise> promise = producer;
        int result = 0;
        producer.resolve();
        {
            AutoWorkQueue awq;
            promise->whenSettled(awq.queue().get(), [&, queue = awq.queue()] {
                assertIsCurrent(queue);
                result = 42;
                queue->beginShutdown();
            });
        }
        EXPECT_EQ(result, 42);
    });
}

// Test that you can convert a NativePromise of different types (exclusive vs non-exclusive)
TEST(NativePromise, PromiseConversion)
{
    using MyPromise = NativePromise<void, int>;
    using MyNonExclusivePromise = NativePromise<void, int, PromiseOption::Default | PromiseOption::NonExclusive>;
    using MyNonExclusiveLongPromise = NativePromise<void, long, PromiseOption::Default | PromiseOption::NonExclusive>;
    runInCurrentRunLoop([](auto& runLoop) {
        auto nonExclusivePromise = MyNonExclusivePromise::createAndResolve();
        Ref<MyPromise> promise1 = nonExclusivePromise.get();
        promise1->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });
        Ref<MyPromise> promise2 = nonExclusivePromise.get();
        promise2->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });

        auto promise3 = nonExclusivePromise->convert<GenericPromise>();
        static_assert(std::is_same_v<Ref<GenericPromise>, decltype(promise3)>);
        promise3->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });

        // Converting a promise taking void as reject.
        auto promise4 = MyNonExclusiveLongPromise::createAndReject(1)->convert<GenericPromise>();
        static_assert(std::is_same_v<Ref<GenericPromise>, decltype(promise4)>);
        promise4->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!result);
        });

        // Converting a promise with different type.
        using IntPromise = NativePromise<int, int>;
        using DoublePromise = NativePromise<double, double>;

        auto promise5 = IntPromise::createAndResolve(1)->convert<DoublePromise>();
        static_assert(std::is_same_v<Ref<DoublePromise>, decltype(promise5)>);
        promise5->whenSettled(runLoop, [](auto&& result) {
            static_assert(std::is_same_v<double, std::remove_reference_t<decltype(result.value())>>);
            EXPECT_TRUE(result.has_value());
        });

        // Can convert to promise taking a data/void mix
        using DoubleVoidPromise = NativePromise<double, void>;
        auto promise6 = IntPromise::createAndReject(1)->convert<DoubleVoidPromise>();
        promise6->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!result);
        });
    });
}

TEST(NativePromise, MismatchChainTo)
{
    using MyPromise = NativePromise<void, int>;
    using MyNonExclusivePromise = NativePromise<void, int, PromiseOption::Default | PromiseOption::NonExclusive>;
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {

        // Chaining resolved promise from producer
        auto nonExclusivePromise = MyNonExclusivePromise::createAndResolve();
        MyPromise::Producer producer1;
        producer1->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });
        nonExclusivePromise->chainTo(WTF::move(producer1));

        // Chaining promise, not yet resolved
        MyNonExclusivePromise::Producer producer2;
        auto promise2 = producer2.promise();
        MyPromise::Producer producer3;
        auto promise3 = producer3.promise();
        promise3->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });
        producer2->chainTo(WTF::move(producer3));
        EXPECT_FALSE(promise2->isSettled());
        EXPECT_FALSE(promise3->isSettled());
        producer2->resolve();
        // Resolving one producer synchronously resolve the other.
        EXPECT_TRUE(promise2->isSettled());
        EXPECT_TRUE(promise3->isSettled());

        // Chaining promise from convertible type
        using IntPromise = NativePromise<int, int>;
        using LongPromise = NativePromise<long, long>;
        auto intPromise1 = IntPromise::createAndResolve(1);
        LongPromise::Producer longPromiseProducer1;
        auto longPromise1 = longPromiseProducer1.promise();
        intPromise1->chainTo(WTF::move(longPromiseProducer1));
        longPromise1->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(1));
        });

        // Chaining non-exclusive promise to exclusive, check the end result is movable.
        using IntPromiseNonExcl = NativePromise<int, int, PromiseOption::Default | PromiseOption::NonExclusive>;
        auto intPromise2 = IntPromiseNonExcl::createAndResolve(1);
        LongPromise::Producer longPromiseProducer2;
        auto longPromise2 = longPromiseProducer2.promise();
        intPromise2->chainTo(WTF::move(longPromiseProducer2));
        longPromise2->whenSettled(runLoop, [](auto&& result) {
            using NonRefQualifiedType = typename std::remove_reference<decltype(result)>::type;
            static_assert(!std::is_const<NonRefQualifiedType>::value, "result is const qualified.");
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(1));
        });
        intPromise2->whenSettled(runLoop, [](auto result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, 1);
        });

        // chaining ThenCommand
        auto intPromise3 = IntPromise::createAndResolve(1);
        LongPromise::Producer longPromiseProducer3;
        auto longPromise3 = longPromiseProducer3.promise();
        longPromise3->whenSettled(runLoop, [&](auto&& result) mutable {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(2));
            done = true;
        });
        intPromise3->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(1));
            return IntPromise::createAndResolve(2);
        })->chainTo(WTF::move(longPromiseProducer3));

        auto intPromise4 = IntPromise::createAndResolve(1);
        LongPromise::Producer longPromiseProducer4;
        auto longPromise4 = longPromiseProducer4.promise();
        intPromise4->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(1));
            return IntPromise::createAndReject(2);
        })->chainTo(WTF::move(longPromiseProducer4));
        longPromise4->whenSettled(runLoop, [&](auto&& result) mutable {
            EXPECT_TRUE(!result);
            EXPECT_EQ(result.error(), long(2));
            done = true;
        });
    });
}

TEST(NativePromise, MismatchChainToVoidPromise)
{
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {
        // chaining with void promise
        using IntPromise = NativePromise<int, int>;
        using LongPromise = NativePromise<long, long>;
        auto intPromise1 = IntPromise::createAndResolve(1);
        LongPromise::Producer longPromiseProducer1;
        auto longPromise1 = longPromiseProducer1.promise();
        intPromise1->chainTo(WTF::move(longPromiseProducer1));
        longPromise1->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(*result, long(1));
        });

        auto intPromise2 = IntPromise::createAndResolve(1);
        GenericPromise::Producer genericPromiseProducer1;
        genericPromiseProducer1->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!!result);
        });
        intPromise2->chainTo(WTF::move(genericPromiseProducer1));

        auto intPromise3 = IntPromise::createAndReject(1);
        GenericPromise::Producer genericPromiseProducer2;
        genericPromiseProducer2->whenSettled(runLoop, [&](auto&& result) {
            EXPECT_TRUE(!result);
            done = true;
        });
        intPromise3->chainTo(WTF::move(genericPromiseProducer2));
    });
}

TEST(NativePromise, CreateSettledPromise)
{
    runInCurrentRunLoopUntilDone([](auto& runLoop, bool& done) {
        using MyExpected = std::expected<int, long>;
        createSettledPromise(MyExpected { makeUnexpected<long>(1) })->whenSettled(runLoop, [](auto&& result) {
            EXPECT_TRUE(!result);
            EXPECT_EQ(result.error(), 1L);
        });
        createSettledPromise(MyExpected { 1 })->whenSettled(runLoop, [&](auto&& result) {
            EXPECT_TRUE(!!result);
            EXPECT_EQ(result.value(), 1);
            done = true;
        });
    });
}

TEST(NativePromise, DisconnectNotOwnedInstance)
{
    GenericPromise::Producer producer;
    auto request = NativePromiseRequest::create();
    WeakPtr weakRequest { request.get() };
    producer->whenSettled(RunLoop::mainSingleton(), [request = WTF::move(request)] (auto&& result) mutable {
        request->complete();
        EXPECT_TRUE(false);
    })->track(*weakRequest);
    weakRequest->disconnect();
    EXPECT_FALSE(!!weakRequest);
    producer.resolve();
}

TEST(NativePromise, AutoRejectProducer)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();
    queue->dispatch([queue] {
        RefPtr<GenericPromise> promise1;
        {
            GenericPromise::AutoRejectProducer producer;
            promise1 = producer.promise();
        }
        promise1->then(queue, doFail(), [] {
            EXPECT_TRUE(true);
        });

        RefPtr<NativePromise<int, int>> promise2;
        {
            NativePromise<int, int>::AutoRejectProducer producer(-1);
            promise2 = producer.promise();
        }
        promise2->then(queue, doFail(), [](auto result) {
            EXPECT_EQ(result, -1);
        });

        // Check that AutoRejectProducer is usable with non-copyable type.
        RefPtr<NativePromise<int, std::unique_ptr<int>>> promise3;
        {
            NativePromise<int, std::unique_ptr<int>>::AutoRejectProducer producer(makeUniqueWithoutFastMallocCheck<int>(-1));
            promise3 = producer.promise();
        }
        promise3->then(queue, doFail(), [](auto&& result) {
            EXPECT_EQ(*result, -1);
        });

        RefPtr<NativePromise<int, std::unique_ptr<int>>> promise4;
        {
            NativePromise<int, std::unique_ptr<int>>::AutoRejectProducer producer(makeUniqueWithoutFastMallocCheck<int>(-2));
            promise4 = producer.promise();
            producer.setDefaultReject(makeUniqueWithoutFastMallocCheck<int>(-1));
        }
        promise4->then(queue, doFail(), [queue](auto&& result) {
            EXPECT_EQ(*result, -1);
            queue->beginShutdown();
        });
    });
}

TEST(NativePromise, ResolveWithFunction)
{
    AutoWorkQueue awq;
    auto queue = awq.queue();

    // Test settled with expected value, before whenSettled.
    NativePromise<int, int>::Producer producer1;
    producer1.settleWithFunction([queue]() -> NativePromise<int, int>::Result {
        assertIsCurrent(queue);
        return 1;
    });
    producer1.promise()->whenSettled(queue, [](auto result) {
        EXPECT_TRUE(!!result);
        EXPECT_EQ(*result, 1);
    });

    // Test settled with rejected value, before whenSettled.
    NativePromise<int, int>::Producer producer2;
    producer2.settleWithFunction([queue]() -> NativePromise<int, int>::Result {
        assertIsCurrent(queue);
        return makeUnexpected(2);
    });
    producer2.promise()->whenSettled(queue, [](auto result) {
        EXPECT_FALSE(!!result);
        EXPECT_EQ(result.error(), 2);
    });

    // Test settled with expected value, after whenSettled.
    NativePromise<int, int>::Producer producer3;
    producer3.promise()->whenSettled(queue, [](auto result) {
        EXPECT_TRUE(!!result);
        EXPECT_EQ(*result, 1);
    });
    producer3.settleWithFunction([queue]() -> NativePromise<int, int>::Result {
        assertIsCurrent(queue);
        return 1;
    });

    // Test settled with rejected value, after whenSettled.
    NativePromise<int, int>::Producer producer4;
    producer4.promise()->whenSettled(queue, [](auto result) {
        EXPECT_FALSE(!!result);
        EXPECT_EQ(result.error(), 2);
    });
    producer4.settleWithFunction([queue]() -> NativePromise<int, int>::Result {
        assertIsCurrent(queue);
        return makeUnexpected(2);
    });

    // Test with settle(Function) syntax
    NativePromise<int, int>::Producer producer5;
    producer5.settle([queue]() -> NativePromise<int, int>::Result {
        assertIsCurrent(queue);
        return 1;
    });
    producer5.promise()->whenSettled(queue, [queue](auto result) {
        EXPECT_TRUE(!!result);
        EXPECT_EQ(*result, 1);
        queue->beginShutdown();
    });
}

// Example:
// Consider a PhotoProducer class that can take a photo and returns an image and its mimetype.
// The PhotoProducer uses some system framework that takes a completion handler which will receive the photo once taken.
// The PhotoProducer uses its own WorkQueue to perform the work so that it won't block the thread it's called on.
// We want the PhotoProducer to be able to be called on any threads.

// This would be the system framework.
struct AVCaptureMethod {
    static void captureImage(std::function<void(std::vector<uint8_t>&&, std::string&&)>&& handler)
    {
        handler({ 1, 2, 3, 4, 5 }, "image/jpeg");
    }
};

struct PhotoSettings { };

// Needed until we get c++23 moveonly_function
template<class F>
auto makeMoveableFunction(F&& f)
{
    return [sharedPtr = std::make_shared<std::decay_t<F>>(std::forward<F>(f))] (auto&&... args) {
        return std::invoke(*sharedPtr, decltype(args)(args)...);
    };
}

class PhotoProducer : public ThreadSafeRefCounted<PhotoProducer> {
public:
    using PhotoPromise = NativePromise<std::pair<Vector<uint8_t>, String>, int>;
    static Ref<PhotoProducer> create(const PhotoSettings& settings) { return adoptRef(*new PhotoProducer(settings)); }

    Ref<PhotoPromise> takePhoto() const
    {
        // This can be called on any threads.
        // It uses invokeAsync which returns a NativePromise that will be settled when the promise returned by the method will itself be settled.
        // (the invokeAsync promise is "chained" to the promise returned by `takePhotoImpl()`)
        return invokeAsync(m_generatePhotoQueue, [protectedThis = Ref { *this }] {
            assertIsCurrent(protectedThis->m_generatePhotoQueue);
            return protectedThis->takePhotoImpl();
        });
    }
private:
    explicit PhotoProducer(const PhotoSettings& settings)
        : m_generatePhotoQueue(WorkQueue::create("takePhoto queue"_s))
    {
    }

    Ref<PhotoPromise> takePhotoImpl() const
    {
        PhotoPromise::Producer producer;
        Ref<PhotoPromise> promise = producer;

        AVCaptureMethod::captureImage(makeMoveableFunction([producer = WTF::move(producer)] (std::vector<uint8_t>&& image, std::string&& mimeType) {
            // Note that you can resolve a NativePromise on any threads. Unlike with a CompletionHandler it is not the responsibility of the producer to resolve the promise
            // on a particular thread.
            // The consumer specifies the thread on which it wants to be called back.
            producer.resolve(std::make_pair<Vector<uint8_t>, String>(std::span { image }, std::span<const char> { mimeType }));
        }));

        // Return the promise which the producer will resolve at a later stage.
        return promise;
    }
    Ref<WorkQueue> m_generatePhotoQueue;
};

TEST(NativePromise, TakePhotoExample)
{
    AutoWorkQueue awk;
    auto queue = awk.queue();
    queue->dispatch([queue] {
        auto photoProducer = PhotoProducer::create(PhotoSettings { });
        photoProducer->takePhoto()->whenSettled(queue, [queue] (PhotoProducer::PhotoPromise::Result&& result) mutable {
            static_assert(std::is_same_v<decltype(result.value()), std::pair<Vector<uint8_t>, String>&>);
            if (result)
                EXPECT_EQ(result.value().second, "image/jpeg"_s);
            else
                EXPECT_TRUE(false); // Got an unexpected error.
            queue->beginShutdown();
        });
    });
}

} // namespace TestWebKitAPI
