/*
 * Copyright (C) 2017 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 "TestMsgQ.h"

namespace android {
namespace hardware {
namespace tests {
namespace msgq {
namespace V1_0 {
namespace implementation {

// Methods from ::android::hardware::tests::msgq::V1_0::ITestMsgQ follow.
Return<bool> TestMsgQ::configureFmqSyncReadWrite(
        const android::hardware::MQDescriptorSync<int32_t>& mqDesc) {
    mFmqSynchronized.reset(new (std::nothrow) MessageQueueSync(mqDesc));
    if ((mFmqSynchronized == nullptr) || (mFmqSynchronized->isValid() == false)) {
        return false;
    }
    /*
     * Initialize the EventFlag word with bit FMQ_NOT_FULL.
     */
    auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord();
    if (evFlagWordPtr != nullptr) {
        std::atomic_init(evFlagWordPtr,
                         static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL));
    }
    return true;
}

Return<void> TestMsgQ::getFmqUnsyncWrite(bool configureFmq, bool userFd,
                                         getFmqUnsyncWrite_cb _hidl_cb) {
    if (configureFmq) {
        static constexpr size_t kNumElementsInQueue = 1024;
        static constexpr size_t kElementSizeBytes = sizeof(int32_t);
        android::base::unique_fd ringbufferFd;
        if (userFd) {
            ringbufferFd.reset(
                    ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kElementSizeBytes));
        }
        mFmqUnsynchronized.reset(new (std::nothrow) MessageQueueUnsync(
                kNumElementsInQueue, false, std::move(ringbufferFd),
                kNumElementsInQueue * kElementSizeBytes));
    }
    if ((mFmqUnsynchronized == nullptr) ||
        (mFmqUnsynchronized->isValid() == false)) {
        _hidl_cb(false /* ret */, MessageQueueUnsync::Descriptor());
    } else {
        _hidl_cb(true /* ret */, *mFmqUnsynchronized->getDesc());
    }
    return Void();
}

Return<bool> TestMsgQ::requestWriteFmqSync(int32_t count) {
    std::vector<int32_t> data(count);
    for (int i = 0; i < count; i++) {
        data[i] = i;
    }
    bool result = mFmqSynchronized->write(&data[0], count);
    return result;
}

Return<bool> TestMsgQ::requestReadFmqSync(int32_t count) {
    std::vector<int32_t> data(count);
    bool result = mFmqSynchronized->read(&data[0], count)
            && verifyData(&data[0], count);
    return result;
}

Return<bool> TestMsgQ::requestWriteFmqUnsync(int32_t count) {
    std::vector<int32_t> data(count);
    for (int i = 0; i < count; i++) {
        data[i] = i;
    }
    bool result = mFmqUnsynchronized->write(&data[0], count);
    return result;
}

Return<bool> TestMsgQ::requestReadFmqUnsync(int32_t count) {
    std::vector<int32_t> data(count);
    bool result =
            mFmqUnsynchronized->read(&data[0], count) && verifyData(&data[0], count);
    return result;
}

Return<void> TestMsgQ::requestBlockingRead(int32_t count) {
    std::vector<int32_t> data(count);
    bool result = mFmqSynchronized->readBlocking(
            &data[0],
            count,
            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
            5000000000 /* timeOutNanos */);

    if (result == false) {
        ALOGE("Blocking read fails");
    }
    return Void();
}

Return<void> TestMsgQ::requestBlockingReadDefaultEventFlagBits(int32_t count) {
    std::vector<int32_t> data(count);
    bool result = mFmqSynchronized->readBlocking(
            &data[0],
            count);

    if (result == false) {
        ALOGE("Blocking read fails");
    }

    return Void();
}

Return<void> TestMsgQ::requestBlockingReadRepeat(int32_t count, int32_t numIter) {
    std::vector<int32_t> data(count);
    for (int i = 0; i < numIter; i++) {
        bool result = mFmqSynchronized->readBlocking(
                &data[0],
                count,
                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
                5000000000 /* timeOutNanos */);

        if (result == false) {
            ALOGE("Blocking read fails");
            break;
        }
    }
    return Void();
}


// Methods from ::android::hidl::base::V1_0::IBase follow.

ITestMsgQ* HIDL_FETCH_ITestMsgQ(const char* /* name */) {
    return new TestMsgQ();
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace msgq
}  // namespace tests
}  // namespace hardware
}  // namespace android
