// 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()
    {
        pollfd pfd = {.fd = client_connection_->GetNotificationChannelFd(), .events = POLLIN};

        int poll_status = poll(&pfd, 1, 5000);
        EXPECT_EQ(1, poll_status);

        uint32_t out_data;
        uint64_t out_data_size;
        // Data was written when the channel was created, so it should be
        // available.
        magma_status_t 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.
        poll_status = poll(&pfd, 1, 0);
        EXPECT_EQ(0, poll_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.
        poll_status = poll(&pfd, 1, 5000);
        EXPECT_EQ(1, poll_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();
}
