// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#pragma once

#include "android/base/Log.h"
#include "android/base/async/Looper.h"
#include "android/base/async/ThreadLooper.h"
#include "android/base/synchronization/Lock.h"
#include "android/emulation/VmLock.h"

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

namespace android {
// All operations that change the global VM state (e.g.
// virtual device operations) should happen in a thread
// that holds the global VM lock.
//
// DeviceContextRunner is a helper template class used
// to ensure that a given operation is always performed
// in such a thread. more specifically:
// - If the current thread already owns the lock,
//   the operation is performed as-is.
// - Otherwise, it is queued and will be run in the
//   main-loop thread as soon as possible.
//
// Usage is the following:
//
// - Define a custom type |OP| corresponding to
//   the state of each operation. It must be copy-able.
//
// - Define a derived class of
//   |DeviceContextRunner<OP>| that must implement the
//   abstract performDeviceOperation(const OP& op) method.
//
// - Create a DeviceContextRunner<OP> instance, and call
//   its init() method, passing a valid android::VmLock
//   instance to it. NOTE: This should be called from
//   the main loop thread, during emulation setup time!!
//
// - Whenever you want to perform an operation, call
//   queueDeviceOperation(<op>) on it. If the current
//   thread holds the lock, it will be
//   performed immediately. Otherwise, it will be queued
//   and run later. Hence the void return type of
//   queueDeviceOperation; it is run asynchronously, so
//   you cannot expect a return value.
template <typename T>
class DeviceContextRunner {
public:
    using AutoLock = android::base::AutoLock;
    using Lock = android::base::Lock;
    using Looper = android::base::Looper;
    using ThreadLooper = android::base::ThreadLooper;
    using VmLock = android::VmLock;
    using PendingList = std::vector<T>;

    void init(VmLock* vmLock) { init(vmLock, ThreadLooper::get()); }

    // Looper parameter is for unit testing purposes.
    void init(VmLock* vmLock, Looper* looper) {
        mVmLock = vmLock;
        // TODO(digit): Find a better event abstraction.
        //
        // Operating on Looper::Timer objects is not supposed to be
        // thread-safe, but it appears that their QEMU1 and QEMU2 specific
        // implementation *is* (see qemu-timer.c:timer_mod()).
        //
        // This means that in practice the code below is safe when used
        // in the context of an Android emulation engine. However, we probably
        // need a better abstraction that also works with the generic
        // Looper implementation (for unit-testing) or any other kind of
        // runtime environment, should we one day link AndroidEmu to a
        // different emulation engine.
        mTimer.reset(looper->createTimer(
                [](void* that, Looper::Timer*) {
                    static_cast<DeviceContextRunner*>(that)->onTimerEvent();
                },
                this));
        if (!mTimer.get()) {
            LOG(WARNING) << "Failed to create a loop timer, falling back "
                            "to regular locking!";
        }
    }

protected:
    // To be implemented by the class that derives DeviceContextRunner:
    // the method that actually touches the virtual device.
    virtual void performDeviceOperation(const T& op) = 0;

    // queueDeviceOperation: If the VM lock is currently held,
    // we are OK to actually perform device operations.
    // Otherwise, we need to add the request to a pending
    // set of requests, to be finished later when we do have the VM lock.
    void queueDeviceOperation(const T& op) {
        if (mVmLock->isLockedBySelf()) {
            // Perform the operation correctly since the current thread
            // already holds the lock that protects the global VM state.
            performDeviceOperation(op);
        } else {
            // Queue the operation in the mPendingMap structure, then
            // restart the timer.
            AutoLock lock(mLock);
            mPending.push_back(op);
            lock.unlock();

            // NOTE: See TODO above why this is thread-safe when used with
            // QEMU1 and QEMU2.
            mTimer->startAbsolute(0);
        }
    }

private:
    void onTimerEvent() {
        // First, clear the current pending set of device commands
        // and operate on each one in turn.
        PendingList pending;
        AutoLock lock(mLock);
        pending.swap(mPending);
        lock.unlock();

        for (const auto& elt : pending) {
            performDeviceOperation(elt);
        }

        // We need to do swap() above so that we can check if
        // the timer needs to be re-armed.
        // (if someone added an event during processing)
        lock.lock();
        if (mPending.size()) {
            mTimer->startAbsolute(0);
        }
    }

    VmLock* mVmLock = nullptr;

    Lock mLock;
    PendingList mPending;
    std::unique_ptr<Looper::Timer> mTimer;
};

}  // namespace android
