// Copyright 2021 The Dawn & Tint Authors
//
// 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.
//
// 3. Neither the name of the copyright holder 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 HOLDER 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.

#ifndef SRC_DAWN_NATIVE_CALLBACKTASKMANAGER_H_
#define SRC_DAWN_NATIVE_CALLBACKTASKMANAGER_H_

#include <functional>
#include <memory>
#include <mutex>
#include <vector>

#include "dawn/common/MutexProtected.h"
#include "dawn/common/RefCounted.h"
#include "dawn/common/TypeTraits.h"

namespace dawn::native {

enum class CallbackState {
    Normal,
    ShutDown,
    DeviceLoss,
};

struct CallbackTask {
  public:
    virtual ~CallbackTask() = default;

    void Execute();
    void OnShutDown();
    void OnDeviceLoss();

  protected:
    virtual void FinishImpl() = 0;
    virtual void HandleShutDownImpl() = 0;
    virtual void HandleDeviceLossImpl() = 0;

  private:
    CallbackState mState = CallbackState::Normal;
};

class CallbackTaskManager : public RefCounted {
  public:
    CallbackTaskManager();
    ~CallbackTaskManager() override;

    void AddCallbackTask(std::unique_ptr<CallbackTask> callbackTask);
    void AddCallbackTask(std::function<void()> callback);
    template <typename... Args>
    void AddCallbackTask(void (*callback)(Args... args), Args... args) {
        static_assert((!IsCString<Args>::value && ...), "passing C string argument is not allowed");

        AddCallbackTask([=] { callback(args...); });
    }
    bool IsEmpty();
    void HandleDeviceLoss();
    void HandleShutDown();
    void Flush();

  private:
    struct StateAndQueue {
        CallbackState mState = CallbackState::Normal;
        std::vector<std::unique_ptr<CallbackTask>> mTaskQueue;
    };
    MutexProtected<StateAndQueue> mStateAndQueue;
};

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_CALLBACKTASKMANAGER_H_
