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

// Unit Test for MediaSampleQueue

// #define LOG_NDEBUG 0
#define LOG_TAG "MediaSampleQueueTests"

#include <android-base/logging.h>
#include <gtest/gtest.h>
#include <media/MediaSampleQueue.h>

#include <thread>

namespace android {

/** Duration to use when delaying threads to order operations. */
static constexpr int64_t kThreadDelayDurationMs = 100;

class MediaSampleQueueTests : public ::testing::Test {
public:
    MediaSampleQueueTests() { LOG(DEBUG) << "MediaSampleQueueTests created"; }
    ~MediaSampleQueueTests() { LOG(DEBUG) << "MediaSampleQueueTests destroyed"; }
};

static std::shared_ptr<MediaSample> newSample(uint32_t id) {
    return MediaSample::createWithReleaseCallback(nullptr /* buffer */, 0 /* offset */, id,
                                                  nullptr /* callback */);
}

TEST_F(MediaSampleQueueTests, TestSequentialDequeueOrder) {
    LOG(DEBUG) << "TestSequentialDequeueOrder Starts";

    static constexpr int kNumSamples = 4;
    MediaSampleQueue sampleQueue;
    EXPECT_TRUE(sampleQueue.isEmpty());

    // Enqueue loop.
    for (int i = 0; i < kNumSamples; ++i) {
        sampleQueue.enqueue(newSample(i));
        EXPECT_FALSE(sampleQueue.isEmpty());
    }

    // Dequeue loop.
    for (int i = 0; i < kNumSamples; ++i) {
        std::shared_ptr<MediaSample> sample;
        bool aborted = sampleQueue.dequeue(&sample);
        EXPECT_NE(sample, nullptr);
        EXPECT_EQ(sample->bufferId, i);
        EXPECT_FALSE(aborted);
    }
    EXPECT_TRUE(sampleQueue.isEmpty());
}

TEST_F(MediaSampleQueueTests, TestInterleavedDequeueOrder) {
    LOG(DEBUG) << "TestInterleavedDequeueOrder Starts";

    static constexpr int kNumSamples = 4;
    MediaSampleQueue sampleQueue;

    // Enqueue and dequeue.
    for (int i = 0; i < kNumSamples; ++i) {
        sampleQueue.enqueue(newSample(i));
        EXPECT_FALSE(sampleQueue.isEmpty());

        std::shared_ptr<MediaSample> sample;
        bool aborted = sampleQueue.dequeue(&sample);
        EXPECT_NE(sample, nullptr);
        EXPECT_EQ(sample->bufferId, i);
        EXPECT_FALSE(aborted);
        EXPECT_TRUE(sampleQueue.isEmpty());
    }
}

TEST_F(MediaSampleQueueTests, TestBlockingDequeue) {
    LOG(DEBUG) << "TestBlockingDequeue Starts";

    MediaSampleQueue sampleQueue;

    std::thread enqueueThread([&sampleQueue] {
        // Note: This implementation is a bit racy. Any amount of sleep will not guarantee that the
        // main thread will be blocked on the sample queue by the time this thread calls enqueue.
        // But we can say with high confidence that it will and the test will not fail regardless.
        std::this_thread::sleep_for(std::chrono::milliseconds(kThreadDelayDurationMs));
        sampleQueue.enqueue(newSample(1));
    });

    std::shared_ptr<MediaSample> sample;
    bool aborted = sampleQueue.dequeue(&sample);
    EXPECT_NE(sample, nullptr);
    EXPECT_EQ(sample->bufferId, 1);
    EXPECT_FALSE(aborted);
    EXPECT_TRUE(sampleQueue.isEmpty());

    enqueueThread.join();
}

TEST_F(MediaSampleQueueTests, TestDequeueBufferRelease) {
    LOG(DEBUG) << "TestDequeueBufferRelease Starts";

    static constexpr int kNumSamples = 4;
    std::vector<bool> bufferReleased(kNumSamples, false);

    MediaSample::OnSampleReleasedCallback callback = [&bufferReleased](MediaSample* sample) {
        bufferReleased[sample->bufferId] = true;
    };

    MediaSampleQueue sampleQueue;
    for (int i = 0; i < kNumSamples; ++i) {
        bool aborted = sampleQueue.enqueue(
                MediaSample::createWithReleaseCallback(nullptr, 0, i, callback));
        EXPECT_FALSE(aborted);
    }

    for (int i = 0; i < kNumSamples; ++i) {
        EXPECT_FALSE(bufferReleased[i]);
    }

    for (int i = 0; i < kNumSamples; ++i) {
        {
            std::shared_ptr<MediaSample> sample;
            bool aborted = sampleQueue.dequeue(&sample);
            EXPECT_NE(sample, nullptr);
            EXPECT_EQ(sample->bufferId, i);
            EXPECT_FALSE(bufferReleased[i]);
            EXPECT_FALSE(aborted);
        }

        for (int j = 0; j < kNumSamples; ++j) {
            EXPECT_EQ(bufferReleased[j], j <= i);
        }
    }
}

TEST_F(MediaSampleQueueTests, TestAbortBufferRelease) {
    LOG(DEBUG) << "TestAbortBufferRelease Starts";

    static constexpr int kNumSamples = 4;
    std::vector<bool> bufferReleased(kNumSamples, false);

    MediaSample::OnSampleReleasedCallback callback = [&bufferReleased](MediaSample* sample) {
        bufferReleased[sample->bufferId] = true;
    };

    MediaSampleQueue sampleQueue;
    for (int i = 0; i < kNumSamples; ++i) {
        bool aborted = sampleQueue.enqueue(
                MediaSample::createWithReleaseCallback(nullptr, 0, i, callback));
        EXPECT_FALSE(aborted);
    }

    for (int i = 0; i < kNumSamples; ++i) {
        EXPECT_FALSE(bufferReleased[i]);
    }

    EXPECT_FALSE(sampleQueue.isEmpty());
    sampleQueue.abort();
    EXPECT_TRUE(sampleQueue.isEmpty());

    for (int i = 0; i < kNumSamples; ++i) {
        EXPECT_TRUE(bufferReleased[i]);
    }
}

TEST_F(MediaSampleQueueTests, TestNonEmptyAbort) {
    LOG(DEBUG) << "TestNonEmptyAbort Starts";

    MediaSampleQueue sampleQueue;
    bool aborted = sampleQueue.enqueue(newSample(1));
    EXPECT_FALSE(aborted);

    sampleQueue.abort();

    std::shared_ptr<MediaSample> sample;
    aborted = sampleQueue.dequeue(&sample);
    EXPECT_TRUE(aborted);
    EXPECT_EQ(sample, nullptr);

    aborted = sampleQueue.enqueue(sample);
    EXPECT_TRUE(aborted);
}

TEST_F(MediaSampleQueueTests, TestEmptyAbort) {
    LOG(DEBUG) << "TestEmptyAbort Starts";

    MediaSampleQueue sampleQueue;
    sampleQueue.abort();

    std::shared_ptr<MediaSample> sample;
    bool aborted = sampleQueue.dequeue(&sample);
    EXPECT_TRUE(aborted);
    EXPECT_EQ(sample, nullptr);

    aborted = sampleQueue.enqueue(sample);
    EXPECT_TRUE(aborted);
}

TEST_F(MediaSampleQueueTests, TestBlockingAbort) {
    LOG(DEBUG) << "TestBlockingAbort Starts";

    MediaSampleQueue sampleQueue;

    std::thread abortingThread([&sampleQueue] {
        // Note: This implementation is a bit racy. Any amount of sleep will not guarantee that the
        // main thread will be blocked on the sample queue by the time this thread calls abort.
        // But we can say with high confidence that it will and the test will not fail regardless.
        std::this_thread::sleep_for(std::chrono::milliseconds(kThreadDelayDurationMs));
        sampleQueue.abort();
    });

    std::shared_ptr<MediaSample> sample;
    bool aborted = sampleQueue.dequeue(&sample);
    EXPECT_TRUE(aborted);
    EXPECT_EQ(sample, nullptr);

    abortingThread.join();
}

}  // namespace android

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
