/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#ifndef FRAMEWORKS_BASE_COMMONPOOL_H
#define FRAMEWORKS_BASE_COMMONPOOL_H

#include <log/log.h>

#include <condition_variable>
#include <functional>
#include <future>
#include <mutex>
#include <vector>

#include "thread/CommonPoolBase.h"
#include "utils/Macros.h"

namespace android {
namespace uirenderer {

template <class T, int SIZE>
class ArrayQueue {
    PREVENT_COPY_AND_ASSIGN(ArrayQueue);
    static_assert(SIZE > 0, "Size must be positive");

public:
    ArrayQueue() = default;
    ~ArrayQueue() = default;

    constexpr size_t capacity() const { return SIZE; }
    constexpr bool hasWork() const { return mHead != mTail; }
    constexpr bool hasSpace() const { return ((mHead + 1) % SIZE) != mTail; }
    constexpr int size() const {
        if (mHead > mTail) {
            return mHead - mTail;
        } else {
            return mTail - mHead + SIZE;
        }
    }

    constexpr void push(T&& t) {
        int newHead = (mHead + 1) % SIZE;
        LOG_ALWAYS_FATAL_IF(newHead == mTail, "no space");

        mBuffer[mHead] = std::move(t);
        mHead = newHead;
    }

    constexpr T pop() {
        LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty");
        int index = mTail;
        mTail = (mTail + 1) % SIZE;
        T ret = std::move(mBuffer[index]);
        mBuffer[index] = nullptr;
        return ret;
    }

private:
    T mBuffer[SIZE];
    int mHead = 0;
    int mTail = 0;
};

class CommonPool : private CommonPoolBase {
    PREVENT_COPY_AND_ASSIGN(CommonPool);

public:
    using Task = std::function<void()>;
    static constexpr auto THREAD_COUNT = 2;
    static constexpr auto QUEUE_SIZE = 128;

    static void post(Task&& func);

    template <class F>
    static auto async(F&& func) -> std::future<decltype(func())> {
        typedef std::packaged_task<decltype(func())()> task_t;
        auto task = std::make_shared<task_t>(std::forward<F>(func));
        post([task]() { std::invoke(*task); });
        return task->get_future();
    }

    template <class F>
    static auto runSync(F&& func) -> decltype(func()) {
        std::packaged_task<decltype(func())()> task{std::forward<F>(func)};
        post([&task]() { std::invoke(task); });
        return task.get_future().get();
    };

    static std::vector<int> getThreadIds();

    // For testing purposes only, blocks until all worker threads are parked.
    static void waitForIdle();

private:
    static CommonPool& instance();

    CommonPool();
    ~CommonPool() {
        mIsStopping = true;
        mCondition.notify_all();
    }

    void enqueue(Task&&);
    void doWaitForIdle();

    void workerLoop();

    std::vector<int> mWorkerThreadIds;

    std::mutex mLock;
    std::condition_variable mCondition;
    int mWaitingThreads = 0;
    ArrayQueue<Task, QUEUE_SIZE> mWorkQueue;
    std::atomic_bool mIsStopping = false;
};

}  // namespace uirenderer
}  // namespace android

#endif  // FRAMEWORKS_BASE_COMMONPOOL_H
