/*
 * Copyright (C) 2018 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.
 */

#pragma once

#include <chrono>
#include <deque>
#include <mutex>
#include <optional>
#include <thread>
#include <tuple>
#include <type_traits>
#include <utility>

#include <android-base/thread_annotations.h>

namespace android {

// This class helps record calls made by another thread when they are made
// asynchronously, with no other way for the tests to verify that the calls have
// been made.
//
// A normal Google Mock recorder, while thread safe, does not allow you to wait
// for asynchronous calls to be made.
//
// Usage:
//
// In the test, use a Google Mock expectation to invoke an instance of the
// recorder:
//
//     AsyncCallRecorder<void(int)> recorder;
//
//     EXPECT_CALL(someMock, someFunction(_)).
//             .WillRepeatedly(Invoke(recorder.getInvocable()));
//
// Then you can invoke the functionality being tested:
//
//     threadUnderTest.doSomethingAsync()
//
// And afterwards make a number of assertions using the recorder:
//
//     // Wait for one call (with reasonable default timeout), and get the args
//     // as a std::tuple inside a std::optional.
//     auto args = recorder.waitForCall();
//     // The returned std::optional will have a value if the recorder function
//     // was called.
//     ASSERT_TRUE(args.has_value());
//     // The arguments can be checked if needed using standard tuple
//     // operations.
//     EXPECT_EQ(123, std::get<0>(args.value()));
//
// Alternatively maybe you want to assert that a call was not made.
//
//     EXPECT_FALSE(recorder.waitForUnexpectedCall().has_value());
//
// However this check uses a really short timeout so as not to block the test
// unnecessarily. And it could be possible for the check to return false and
// then the recorder could observe a call being made after.
template <typename Func>
class AsyncCallRecorder;

template <typename... Args>
class AsyncCallRecorder<void (*)(Args...)> {
public:
    // For the tests, we expect the wait for an expected change to be signaled
    // to be much shorter than this.
    static constexpr std::chrono::milliseconds DEFAULT_CALL_EXPECTED_TIMEOUT{10};

    // The wait here is tricky. We don't expect a change, but we don't want to
    // wait forever (or for longer than the typical test function runtime). As
    // even the simplest Google Test can take 1ms (1000us) to run, we wait for
    // half that time.
    static constexpr std::chrono::microseconds UNEXPECTED_CALL_TIMEOUT{500};

    using ArgTuple = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;

    void recordCall(Args... args) {
        std::lock_guard<std::mutex> lock(mMutex);
        mCalls.emplace_back(std::make_tuple(args...));
        mCondition.notify_all();
    }

    // Returns a functor which can be used with the Google Mock Invoke()
    // function, or as a std::function to record calls.
    auto getInvocable() {
        return [this](Args... args) { recordCall(args...); };
    }

    // Returns a set of arguments as a std::optional<std::tuple<...>> for the
    // oldest call, waiting for the given timeout if necessary if there are no
    // arguments in the FIFO.
    std::optional<ArgTuple> waitForCall(
            std::chrono::microseconds timeout = DEFAULT_CALL_EXPECTED_TIMEOUT)
            NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);

        // Wait if necessary for us to have a record from a call.
        mCondition.wait_for(lock, timeout,
                            [this]() NO_THREAD_SAFETY_ANALYSIS { return !mCalls.empty(); });

        // Return the arguments from the oldest call, if one was made
        bool called = !mCalls.empty();
        std::optional<ArgTuple> result;
        if (called) {
            result.emplace(std::move(mCalls.front()));
            mCalls.pop_front();
        }
        return result;
    }

    // Waits using a small default timeout for when a call is not expected to be
    // made. The returned std::optional<std:tuple<...>> should not have a value
    // except if a set of arguments was unexpectedly received because a call was
    // actually made.
    //
    // Note this function uses a small timeout to not block test execution, and
    // it is possible the code under test could make the call AFTER the timeout
    // expires.
    std::optional<ArgTuple> waitForUnexpectedCall() { return waitForCall(UNEXPECTED_CALL_TIMEOUT); }

private:
    std::mutex mMutex;
    std::condition_variable mCondition;
    std::deque<ArgTuple> mCalls GUARDED_BY(mMutex);
};

// Like AsyncCallRecorder, but for when the function being invoked
// asynchronously is expected to return a value.
//
// This helper allows a single constant return value to be set to be returned by
// all calls that were made.
template <typename Func>
class AsyncCallRecorderWithCannedReturn;

template <typename Ret, typename... Args>
class AsyncCallRecorderWithCannedReturn<Ret (*)(Args...)>
      : public AsyncCallRecorder<void (*)(Args...)> {
public:
    explicit AsyncCallRecorderWithCannedReturn(Ret returnvalue) : mReturnValue(returnvalue) {}

    auto getInvocable() {
        return [this](Args... args) {
            this->recordCall(args...);
            return mReturnValue;
        };
    }

private:
    const Ret mReturnValue;
};

} // namespace android
