// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn_platform/WorkerThread.h"

#include <condition_variable>
#include <functional>
#include <thread>

#include "common/Assert.h"

namespace {

    class AsyncWaitableEventImpl {
      public:
        AsyncWaitableEventImpl() : mIsComplete(false) {
        }

        void Wait() {
            std::unique_lock<std::mutex> lock(mMutex);
            mCondition.wait(lock, [this] { return mIsComplete; });
        }

        bool IsComplete() {
            std::lock_guard<std::mutex> lock(mMutex);
            return mIsComplete;
        }

        void MarkAsComplete() {
            {
                std::lock_guard<std::mutex> lock(mMutex);
                mIsComplete = true;
            }
            mCondition.notify_all();
        }

      private:
        std::mutex mMutex;
        std::condition_variable mCondition;
        bool mIsComplete;
    };

    class AsyncWaitableEvent final : public dawn_platform::WaitableEvent {
      public:
        explicit AsyncWaitableEvent()
            : mWaitableEventImpl(std::make_shared<AsyncWaitableEventImpl>()) {
        }

        void Wait() override {
            mWaitableEventImpl->Wait();
        }

        bool IsComplete() override {
            return mWaitableEventImpl->IsComplete();
        }

        std::shared_ptr<AsyncWaitableEventImpl> GetWaitableEventImpl() const {
            return mWaitableEventImpl;
        }

      private:
        std::shared_ptr<AsyncWaitableEventImpl> mWaitableEventImpl;
    };

}  // anonymous namespace

namespace dawn_platform {

    std::unique_ptr<dawn_platform::WaitableEvent> AsyncWorkerThreadPool::PostWorkerTask(
        dawn_platform::PostWorkerTaskCallback callback,
        void* userdata) {
        std::unique_ptr<AsyncWaitableEvent> waitableEvent = std::make_unique<AsyncWaitableEvent>();

        std::function<void()> doTask =
            [callback, userdata, waitableEventImpl = waitableEvent->GetWaitableEventImpl()]() {
                callback(userdata);
                waitableEventImpl->MarkAsComplete();
            };

        std::thread thread(doTask);
        thread.detach();

        return waitableEvent;
    }

}  // namespace dawn_platform
