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

#include "AutoConditionLock.h"

namespace android {

WaitableMutexWrapper::WaitableMutexWrapper(Mutex* mutex) : mMutex{mutex}, mState{false} {}

WaitableMutexWrapper::~WaitableMutexWrapper() {}

// Locks manager-owned mutex
AutoConditionLock::AutoConditionLock(const std::shared_ptr<WaitableMutexWrapper>& manager) :
        mManager{manager}, mAutoLock{manager->mMutex} {}

// Unlocks manager-owned mutex
AutoConditionLock::~AutoConditionLock() {
    // Unset the condition and wake everyone up before releasing lock
    mManager->mState = false;
    mManager->mCondition.broadcast();
}

std::unique_ptr<AutoConditionLock> AutoConditionLock::waitAndAcquire(
        const std::shared_ptr<WaitableMutexWrapper>& manager, nsecs_t waitTime) {

    if (manager == nullptr || manager->mMutex == nullptr) {
        // Bad input, return null
        return std::unique_ptr<AutoConditionLock>{nullptr};
    }

    // Acquire scoped lock
    std::unique_ptr<AutoConditionLock> scopedLock(new AutoConditionLock(manager));

    // Figure out what time in the future we should hit the timeout
    nsecs_t failTime = systemTime(SYSTEM_TIME_MONOTONIC) + waitTime;

    // Wait until we timeout, or success
    while(manager->mState) {
        status_t ret = manager->mCondition.waitRelative(*(manager->mMutex), waitTime);
        if (ret != NO_ERROR) {
            // Timed out or whatever, return null
            return std::unique_ptr<AutoConditionLock>{nullptr};
        }
        waitTime = failTime - systemTime(SYSTEM_TIME_MONOTONIC);
    }

    // Set the condition and return
    manager->mState = true;
    return scopedLock;
}

std::unique_ptr<AutoConditionLock> AutoConditionLock::waitAndAcquire(
        const std::shared_ptr<WaitableMutexWrapper>& manager) {

    if (manager == nullptr || manager->mMutex == nullptr) {
        // Bad input, return null
        return std::unique_ptr<AutoConditionLock>{nullptr};
    }

    // Acquire scoped lock
    std::unique_ptr<AutoConditionLock> scopedLock(new AutoConditionLock(manager));

    // Wait until we timeout, or success
    while(manager->mState) {
        status_t ret = manager->mCondition.wait(*(manager->mMutex));
        if (ret != NO_ERROR) {
            // Timed out or whatever, return null
            return std::unique_ptr<AutoConditionLock>{nullptr};
        }
    }

    // Set the condition and return
    manager->mState = true;
    return scopedLock;
}

}; // namespace android
