// 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 <fcntl.h>
#include <poll.h>

#include "magma.h"
#include "magma_util/dlog.h"
#include "magma_util/macros.h"
#include "platform_buffer.h"
#include "gtest/gtest.h"
#include <thread>

extern "C" {
#include "test_magma_abi.h"
}

class TestConnection {
public:
    TestConnection()
    {
        fd_ = open("/dev/class/gpu/000", O_RDONLY);
        DASSERT(fd_ >= 0);
        magma_create_connection(fd(), &connection_);
    }

    ~TestConnection()
    {
        if (connection_)
            magma_release_connection(connection_);

        close(fd_);
    }

    int fd() { return fd_; }

    void GetDeviceId()
    {
        uint64_t device_id = 0;
        EXPECT_EQ(MAGMA_STATUS_OK, magma_query(fd_, MAGMA_QUERY_DEVICE_ID, &device_id));
        EXPECT_NE(0u, device_id);
    }

    magma_connection_t connection() { return connection_; }

    void Connection() { ASSERT_NE(connection_, nullptr); }

    void Context()
    {
        ASSERT_NE(connection_, nullptr);

        uint32_t context_id[2];

        magma_create_context(connection_, &context_id[0]);
        EXPECT_EQ(magma_get_error(connection_), 0);

        magma_create_context(connection_, &context_id[1]);
        EXPECT_EQ(magma_get_error(connection_), 0);

        magma_release_context(connection_, context_id[0]);
        EXPECT_EQ(magma_get_error(connection_), 0);

        magma_release_context(connection_, context_id[1]);
        EXPECT_EQ(magma_get_error(connection_), 0);

        magma_release_context(connection_, context_id[1]);
        EXPECT_NE(magma_get_error(connection_), 0);
    }

    void NotificationFd()
    {
        int fd1 = magma_get_notification_channel_fd(connection_);
        EXPECT_LE(0, fd1);

        int fd2 = magma_get_notification_channel_fd(connection_);
        EXPECT_LE(0, fd1);
        EXPECT_NE(fd1, fd2);

        struct pollfd fds[2] = {{fd1, POLLIN, 0}, {fd2, POLLOUT, 0}};
        int result = poll(fds, 2, 0);

        // No events should exist.
        EXPECT_EQ(0, result);
        EXPECT_EQ(0, fds[0].revents);
        EXPECT_EQ(0, fds[1].revents);
        close(fd1);
        close(fd2);
    }

    void NotificationChannel()
    {
        uint32_t handle = magma_get_notification_channel_handle(connection_);
        EXPECT_NE(0u, handle);

        uint32_t handle2 = magma_get_notification_channel_handle(connection_);
        EXPECT_EQ(handle, handle2);
    }

    void Buffer()
    {
        ASSERT_NE(connection_, nullptr);

        uint64_t size = PAGE_SIZE;
        uint64_t actual_size;
        uint64_t id;

        EXPECT_EQ(magma_create_buffer(connection_, size, &actual_size, &id), 0);
        EXPECT_GE(size, actual_size);
        EXPECT_NE(id, 0u);

        magma_release_buffer(connection_, id);
    }

    void BufferMap()
    {
        ASSERT_NE(connection_, nullptr);

        uint64_t size = PAGE_SIZE;
        uint64_t actual_size;
        uint64_t id;

        EXPECT_EQ(magma_create_buffer(connection_, size, &actual_size, &id), 0);
        EXPECT_NE(id, 0u);

        magma_map_buffer_gpu(connection_, id, 1024, 0, size / PAGE_SIZE, MAGMA_GPU_MAP_FLAG_READ);
        magma_unmap_buffer_gpu(connection_, id, 2048);
        magma_commit_buffer(connection_, id, 100, 100);

        magma_release_buffer(connection_, id);
    }

    void BufferExport(uint32_t* handle_out, uint64_t* id_out)
    {
        ASSERT_NE(connection_, nullptr);

        uint64_t size = PAGE_SIZE;
        magma_buffer_t buffer;

        EXPECT_EQ(magma_create_buffer(connection_, size, &size, &buffer), 0);

        *id_out = magma_get_buffer_id(buffer);

        EXPECT_EQ(magma_export(connection_, buffer, handle_out), 0);
    }

    void BufferImport(uint32_t handle, uint64_t id)
    {
        ASSERT_NE(connection_, nullptr);

        magma_buffer_t buffer;
        EXPECT_EQ(magma_import(connection_, handle, &buffer), 0);
        EXPECT_EQ(magma_get_buffer_id(buffer), id);
    }

    static void BufferImportExport(TestConnection* test1, TestConnection* test2)
    {
        uint32_t handle;
        uint64_t id;
        test1->BufferExport(&handle, &id);
        test2->BufferImport(handle, id);
    }

    void Semaphore(uint32_t count)
    {
        ASSERT_NE(connection_, nullptr);

        std::vector<magma_semaphore_t> semaphore(count);
        for (uint32_t i = 0; i < count; i++) {
            EXPECT_EQ(MAGMA_STATUS_OK, magma_create_semaphore(connection_, &semaphore[i]));
            EXPECT_NE(0u, magma_get_semaphore_id(semaphore[i]));
        }

        auto thread = std::thread([semaphore, wait_all = true] {
            EXPECT_EQ(MAGMA_STATUS_OK, magma_wait_semaphores(semaphore.data(), semaphore.size(),
                                                             UINT64_MAX, wait_all));
            for (uint32_t i = 0; i < semaphore.size(); i++) {
                magma_reset_semaphore(semaphore[i]);
            }
            EXPECT_EQ(MAGMA_STATUS_TIMED_OUT,
                      magma_wait_semaphores(semaphore.data(), semaphore.size(), 100, wait_all));
        });

        for (uint32_t i = 0; i < semaphore.size(); i++) {
            usleep(10 * 1000);
            magma_signal_semaphore(semaphore[i]);
        }
        thread.join();

        thread = std::thread([semaphore, wait_all = false] {
            EXPECT_EQ(MAGMA_STATUS_OK, magma_wait_semaphores(semaphore.data(), semaphore.size(),
                                                             UINT64_MAX, wait_all));
            for (uint32_t i = 0; i < semaphore.size(); i++) {
                magma_reset_semaphore(semaphore[i]);
            }
            EXPECT_EQ(MAGMA_STATUS_TIMED_OUT,
                      magma_wait_semaphores(semaphore.data(), semaphore.size(), 100, wait_all));
        });

        usleep(10 * 1000);
        magma_signal_semaphore(semaphore[semaphore.size() - 1]);
        thread.join();

        for (uint32_t i = 0; i < semaphore.size(); i++) {
            magma_release_semaphore(connection_, semaphore[i]);
        }
    }

    void SemaphoreExport(uint32_t* handle_out, uint64_t* id_out)
    {
        ASSERT_NE(connection_, nullptr);
        magma_semaphore_t semaphore;

        EXPECT_EQ(magma_create_semaphore(connection_, &semaphore), MAGMA_STATUS_OK);
        *id_out = magma_get_semaphore_id(semaphore);
        EXPECT_EQ(magma_export_semaphore(connection_, semaphore, handle_out), MAGMA_STATUS_OK);
    }

    void SemaphoreImport(uint32_t handle, uint64_t id)
    {
        ASSERT_NE(connection_, nullptr);
        magma_semaphore_t semaphore;

        EXPECT_EQ(magma_import_semaphore(connection_, handle, &semaphore), MAGMA_STATUS_OK);
        EXPECT_EQ(magma_get_semaphore_id(semaphore), id);
    }

    static void SemaphoreImportExport(TestConnection* test1, TestConnection* test2)
    {
        uint32_t handle;
        uint64_t id;
        test1->SemaphoreExport(&handle, &id);
        test2->SemaphoreImport(handle, id);
    }

private:
    int fd_ = -1;
    magma_connection_t connection_;
};

TEST(MagmaAbi, DeviceId)
{
    TestConnection test;
    test.GetDeviceId();
}

TEST(MagmaAbi, Buffer)
{
    TestConnection test;
    test.Buffer();
}

TEST(MagmaAbi, Connection)
{
    TestConnection test;
    test.Connection();
}

TEST(MagmaAbi, Context)
{
    TestConnection test;
    test.Context();
}

TEST(MagmaAbi, NotificationFd)
{
    TestConnection test;
    test.NotificationFd();
}

TEST(MagmaAbi, NotificationChannel)
{
    TestConnection test;
    test.NotificationChannel();
}

TEST(MagmaAbi, BufferMap)
{
    TestConnection test;
    test.BufferMap();
}

TEST(MagmaAbi, BufferImportExport)
{
    TestConnection test1;
    TestConnection test2;
    TestConnection::BufferImportExport(&test1, &test2);
}

TEST(MagmaAbi, Semaphore)
{
    TestConnection test;
    test.Semaphore(1);
    test.Semaphore(2);
    test.Semaphore(3);
}

TEST(MagmaAbi, SemaphoreImportExport)
{
    TestConnection test1;
    TestConnection test2;
    TestConnection::SemaphoreImportExport(&test1, &test2);
}

TEST(MagmaAbi, FromC) { EXPECT_TRUE(test_magma_abi_from_c()); }
