// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "platform_connection.h"
#include "platform_connection_client.h"
#include "gtest/gtest.h"
#include <chrono>
#include <poll.h>
#include <thread>

namespace {
constexpr uint32_t kImmediateCommandCount = 128;
// The total size of all commands should not be a multiple of the receive buffer size.
constexpr uint32_t kImmediateCommandSize = 2048 * 3 / 2 / kImmediateCommandCount;
} // namespace

class TestPlatformConnection {
public:
    static std::unique_ptr<TestPlatformConnection> Create();

    TestPlatformConnection(std::unique_ptr<magma::PlatformConnectionClient> client_connection,
                           std::thread ipc_thread,
                           std::shared_ptr<magma::PlatformConnection> connection)
        : client_connection_(std::move(client_connection)), ipc_thread_(std::move(ipc_thread)),
          connection_(std::move(connection))
    {
    }

    ~TestPlatformConnection()
    {
        client_connection_.reset();
        connection_.reset();
        if (ipc_thread_.joinable())
            ipc_thread_.join();
        EXPECT_TRUE(test_complete);
    }

    void TestImportBuffer()
    {
        auto buf = magma::PlatformBuffer::Create(1, "test");
        test_buffer_id = buf->id();
        EXPECT_EQ(client_connection_->ImportBuffer(buf.get()), 0);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }
    void TestReleaseBuffer()
    {
        auto buf = magma::PlatformBuffer::Create(1, "test");
        test_buffer_id = buf->id();
        EXPECT_EQ(client_connection_->ImportBuffer(buf.get()), 0);
        EXPECT_EQ(client_connection_->ReleaseBuffer(test_buffer_id), 0);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestImportObject()
    {
        auto semaphore = magma::PlatformSemaphore::Create();
        test_semaphore_id = semaphore->id();
        uint32_t handle;
        EXPECT_TRUE(semaphore->duplicate_handle(&handle));
        EXPECT_EQ(client_connection_->ImportObject(handle, magma::PlatformObject::SEMAPHORE), 0);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }
    void TestReleaseObject()
    {
        auto semaphore = magma::PlatformSemaphore::Create();
        test_semaphore_id = semaphore->id();
        uint32_t handle;
        EXPECT_TRUE(semaphore->duplicate_handle(&handle));
        EXPECT_EQ(client_connection_->ImportObject(handle, magma::PlatformObject::SEMAPHORE), 0);
        EXPECT_EQ(
            client_connection_->ReleaseObject(test_semaphore_id, magma::PlatformObject::SEMAPHORE),
            0);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestCreateContext()
    {
        uint32_t context_id;
        client_connection_->CreateContext(&context_id);
        EXPECT_EQ(client_connection_->GetError(), 0);
        EXPECT_EQ(test_context_id, context_id);
    }
    void TestDestroyContext()
    {
        client_connection_->DestroyContext(test_context_id);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestExecuteCommandBuffer()
    {
        auto buf = magma::PlatformBuffer::Create(1, "test");
        test_buffer_id = buf->id();
        uint32_t handle;
        EXPECT_TRUE(buf->duplicate_handle(&handle));
        client_connection_->ExecuteCommandBuffer(handle, test_context_id);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestGetError()
    {
        EXPECT_EQ(client_connection_->GetError(), 0);
        test_complete = true;
    }

    void TestMapUnmapBuffer()
    {
        auto buf = magma::PlatformBuffer::Create(1, "test");
        test_buffer_id = buf->id();
        EXPECT_EQ(client_connection_->ImportBuffer(buf.get()), 0);
        EXPECT_EQ(client_connection_->MapBufferGpu(buf->id(), PAGE_SIZE * 1000, 1u, 2u, 5), 0);
        EXPECT_EQ(client_connection_->UnmapBufferGpu(buf->id(), PAGE_SIZE * 1000), 0);
        EXPECT_EQ(client_connection_->CommitBuffer(buf->id(), 1000, 2000), 0);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestNotificationChannel()
    {
        constexpr uint64_t kFiveSecondsInNs = 5000000000;
        magma_status_t status = client_connection_->WaitNotificationChannel(kFiveSecondsInNs);
        EXPECT_EQ(MAGMA_STATUS_OK, status);

        uint32_t out_data;
        uint64_t out_data_size;
        // Data was written when the channel was created, so it should be
        // available.
        status = client_connection_->ReadNotificationChannel(&out_data, sizeof(out_data),
                                                             &out_data_size);
        EXPECT_EQ(MAGMA_STATUS_OK, status);
        EXPECT_EQ(sizeof(out_data), out_data_size);
        EXPECT_EQ(5u, out_data);

        // No more data to read.
        status = client_connection_->WaitNotificationChannel(0);
        EXPECT_EQ(MAGMA_STATUS_TIMED_OUT, status);

        status = client_connection_->ReadNotificationChannel(&out_data, sizeof(out_data),
                                                             &out_data_size);
        EXPECT_EQ(MAGMA_STATUS_OK, status);
        EXPECT_EQ(0u, out_data_size);

        // Shutdown other end of pipe.
        connection_->ShutdownEvent()->Signal();
        connection_.reset();
        ipc_thread_.join();
        EXPECT_TRUE(got_null_notification);

        // Poll should still terminate early.
        status = client_connection_->WaitNotificationChannel(kFiveSecondsInNs);
        EXPECT_EQ(MAGMA_STATUS_CONNECTION_LOST, status);

        status = client_connection_->ReadNotificationChannel(&out_data, sizeof(out_data),
                                                             &out_data_size);
        EXPECT_EQ(MAGMA_STATUS_CONNECTION_LOST, status);
        test_complete = true;
    }

    void TestExecuteImmediateCommands()
    {
        uint8_t commands_buffer[kImmediateCommandSize * kImmediateCommandCount] = {};
        uint64_t semaphore_ids[]{0, 1, 2};
        magma_system_inline_command_buffer commands[kImmediateCommandCount];
        for (size_t i = 0; i < kImmediateCommandCount; i++) {
            commands[i].data = commands_buffer;
            commands[i].size = kImmediateCommandSize;
            commands[i].semaphore_count = 3;
            commands[i].semaphores = semaphore_ids;
        }

        client_connection_->ExecuteImmediateCommands(test_context_id, kImmediateCommandCount,
                                                     commands);
        EXPECT_EQ(client_connection_->GetError(), 0);
    }

    void TestMultipleGetError()
    {
        std::vector<std::thread> threads;
        for (uint32_t i = 0; i < 1000; i++) {
            threads.push_back(std::thread(
                [this]() { EXPECT_EQ(MAGMA_STATUS_OK, client_connection_->GetError()); }));
        }

        for (auto& thread : threads) {
            thread.join();
        }
        test_complete = true;
    }

    static uint64_t test_buffer_id;
    static uint32_t test_context_id;
    static uint64_t test_semaphore_id;
    static bool got_null_notification;
    static magma_status_t test_error;
    static bool test_complete;
    static std::unique_ptr<magma::PlatformSemaphore> test_semaphore;

private:
    static void IpcThreadFunc(std::shared_ptr<magma::PlatformConnection> connection)
    {
        while (connection->HandleRequest())
            ;
    }

    std::unique_ptr<magma::PlatformConnectionClient> client_connection_;
    std::thread ipc_thread_;
    std::shared_ptr<magma::PlatformConnection> connection_;
};

uint64_t TestPlatformConnection::test_buffer_id;
uint64_t TestPlatformConnection::test_semaphore_id;
uint32_t TestPlatformConnection::test_context_id;
magma_status_t TestPlatformConnection::test_error;
bool TestPlatformConnection::test_complete;
std::unique_ptr<magma::PlatformSemaphore> TestPlatformConnection::test_semaphore;
bool TestPlatformConnection::got_null_notification;

class TestDelegate : public magma::PlatformConnection::Delegate {
public:
    bool ImportBuffer(uint32_t handle, uint64_t* buffer_id_out) override
    {
        auto buf = magma::PlatformBuffer::Import(handle);
        EXPECT_EQ(buf->id(), TestPlatformConnection::test_buffer_id);
        TestPlatformConnection::test_complete = true;
        return true;
    }
    bool ReleaseBuffer(uint64_t buffer_id) override
    {
        EXPECT_EQ(buffer_id, TestPlatformConnection::test_buffer_id);
        TestPlatformConnection::test_complete = true;
        return true;
    }

    bool ImportObject(uint32_t handle, magma::PlatformObject::Type object_type) override
    {
        auto semaphore = magma::PlatformSemaphore::Import(handle);
        EXPECT_EQ(semaphore->id(), TestPlatformConnection::test_semaphore_id);
        TestPlatformConnection::test_complete = true;
        return true;
    }
    bool ReleaseObject(uint64_t object_id, magma::PlatformObject::Type object_type) override
    {
        EXPECT_EQ(object_id, TestPlatformConnection::test_semaphore_id);
        TestPlatformConnection::test_complete = true;
        return true;
    }

    bool CreateContext(uint32_t context_id) override
    {
        TestPlatformConnection::test_context_id = context_id;
        TestPlatformConnection::test_complete = true;
        return true;
    }
    bool DestroyContext(uint32_t context_id) override
    {
        EXPECT_EQ(context_id, TestPlatformConnection::test_context_id);
        TestPlatformConnection::test_complete = true;
        return true;
    }

    magma::Status ExecuteCommandBuffer(uint32_t command_buffer_handle, uint32_t context_id) override
    {
        auto buffer = magma::PlatformBuffer::Import(command_buffer_handle);
        EXPECT_EQ(buffer->id(), TestPlatformConnection::test_buffer_id);
        EXPECT_EQ(context_id, TestPlatformConnection::test_context_id);
        TestPlatformConnection::test_complete = true;
        return MAGMA_STATUS_OK;
    }

    bool MapBufferGpu(uint64_t buffer_id, uint64_t gpu_va, uint64_t page_offset,
                      uint64_t page_count, uint64_t flags) override
    {
        EXPECT_EQ(TestPlatformConnection::test_buffer_id, buffer_id);
        EXPECT_EQ(PAGE_SIZE * 1000lu, gpu_va);
        EXPECT_EQ(1u, page_offset);
        EXPECT_EQ(2u, page_count);
        EXPECT_EQ(5u, flags);
        return true;
    }

    bool UnmapBufferGpu(uint64_t buffer_id, uint64_t gpu_va) override
    {
        EXPECT_EQ(TestPlatformConnection::test_buffer_id, buffer_id);
        EXPECT_EQ(PAGE_SIZE * 1000lu, gpu_va);
        return true;
    }

    bool CommitBuffer(uint64_t buffer_id, uint64_t page_offset, uint64_t page_count) override
    {
        EXPECT_EQ(TestPlatformConnection::test_buffer_id, buffer_id);
        EXPECT_EQ(1000lu, page_offset);
        EXPECT_EQ(2000lu, page_count);
        return true;
    }

    void SetNotificationCallback(msd_connection_notification_callback_t callback,
                                 void* token) override
    {
        if (!token) {
            // This doesn't count as test complete because it should happen in every test when the
            // server shuts down.
            TestPlatformConnection::got_null_notification = true;
        } else {
            uint32_t data = 5;
            msd_notification_t n = {.type = MSD_CONNECTION_NOTIFICATION_CHANNEL_SEND};
            *reinterpret_cast<uint32_t*>(n.u.channel_send.data) = data;
            n.u.channel_send.size = sizeof(data);
            callback(token, &n);
        }
    }

    magma::Status ExecuteImmediateCommands(uint32_t context_id, uint64_t commands_size,
                                           void* commands, uint64_t semaphore_count,
                                           uint64_t* semaphores) override
    {
        EXPECT_GE(2048u, commands_size);
        uint8_t received_bytes[2048] = {};
        EXPECT_EQ(0, memcmp(received_bytes, commands, commands_size));
        uint64_t command_count = commands_size / kImmediateCommandSize;
        EXPECT_EQ(3u * command_count, semaphore_count);
        for (uint32_t i = 0; i < command_count; i++) {
            EXPECT_EQ(0u, semaphores[0]);
            EXPECT_EQ(1u, semaphores[1]);
            EXPECT_EQ(2u, semaphores[2]);
            semaphores += 3;
        }
        immediate_commands_bytes_executed_ += commands_size;
        TestPlatformConnection::test_complete =
            immediate_commands_bytes_executed_ == kImmediateCommandSize * kImmediateCommandCount;

        return MAGMA_STATUS_OK;
    }

    uint64_t immediate_commands_bytes_executed_ = 0;
};

std::unique_ptr<TestPlatformConnection> TestPlatformConnection::Create()
{
    test_buffer_id = 0xcafecafecafecafe;
    test_semaphore_id = ~0u;
    test_context_id = 0xdeadbeef;
    test_error = 0x12345678;
    test_complete = false;
    got_null_notification = false;
    auto delegate = std::make_unique<TestDelegate>();

    auto connection = magma::PlatformConnection::Create(std::move(delegate));
    if (!connection)
        return DRETP(nullptr, "failed to create PlatformConnection");
    auto client_connection = magma::PlatformConnectionClient::Create(
        connection->GetClientEndpoint(), connection->GetClientNotificationEndpoint());
    if (!client_connection)
        return DRETP(nullptr, "failed to create PlatformConnectionClient");

    auto ipc_thread = std::thread(IpcThreadFunc, connection);

    return std::make_unique<TestPlatformConnection>(std::move(client_connection),
                                                    std::move(ipc_thread), connection);
}

TEST(PlatformConnection, GetError)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestGetError();
}

TEST(PlatformConnection, ImportBuffer)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestImportBuffer();
}

TEST(PlatformConnection, ReleaseBuffer)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestReleaseBuffer();
}

TEST(PlatformConnection, ImportObject)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestImportObject();
}

TEST(PlatformConnection, ReleaseObject)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestReleaseObject();
}

TEST(PlatformConnection, CreateContext)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestCreateContext();
}

TEST(PlatformConnection, DestroyContext)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestDestroyContext();
}

TEST(PlatformConnection, ExecuteCommandBuffer)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestExecuteCommandBuffer();
}

TEST(PlatformConnection, MapUnmapBuffer)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestMapUnmapBuffer();
}

TEST(PlatformConnection, NotificationChannel)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestNotificationChannel();
}

TEST(PlatformConnection, ExecuteImmediateCommands)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestExecuteImmediateCommands();
}

TEST(PlatformConnection, MultipleGetError)
{
    auto Test = TestPlatformConnection::Create();
    ASSERT_NE(Test, nullptr);
    Test->TestMultipleGetError();
}
