// Copyright 2017 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 "helper/command_buffer_helper.h"
#include "helper/platform_device_helper.h"
#include "magma_arm_mali_types.h"
#include "sys_driver/magma_driver.h"
#include "sys_driver/magma_system_connection.h"
#include "sys_driver/magma_system_context.h"
#include "gtest/gtest.h"

namespace {

class Test {
public:
    void TestValidImmediate()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom[2];
        atom[0].size = sizeof(atom[0]);
        atom[0].atom_number = 1;
        atom[0].flags = 1;
        atom[0].dependencies[0].atom_number = 0;
        atom[0].dependencies[1].atom_number = 0;
        atom[1].size = sizeof(atom[1]);
        atom[1].atom_number = 2;
        atom[1].flags = 1;
        atom[1].dependencies[0].atom_number = 1;
        atom[1].dependencies[0].type = kArmMaliDependencyOrder;
        atom[1].dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_OK, status.get());
    }

    void TestValidLarger()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        uint8_t buffer[100];
        ASSERT_GT(sizeof(buffer), sizeof(magma_arm_mali_atom));
        auto atom = reinterpret_cast<magma_arm_mali_atom*>(buffer);
        atom->size = sizeof(buffer);
        atom->atom_number = 1;
        atom->flags = 1;
        atom->dependencies[0].atom_number = 0;
        atom->dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(buffer), buffer, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_OK, status.get());
    }

    void TestInvalidTooLarge()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        uint8_t buffer[100];
        ASSERT_GT(sizeof(buffer), sizeof(magma_arm_mali_atom) + 1);
        auto atom = reinterpret_cast<magma_arm_mali_atom*>(buffer);
        atom->size = sizeof(buffer);
        atom->atom_number = 1;
        atom->flags = 1;
        atom->dependencies[0].atom_number = 0;
        atom->dependencies[1].atom_number = 0;

        magma::Status status =
            ctx->ExecuteImmediateCommands(sizeof(buffer) - 1, buffer, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidOverflow()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom[3];
        for (uint32_t i = 0; i < 3; i++) {
            atom[i].size = sizeof(atom[i]);
            atom[i].atom_number = i + 1;
            atom[i].flags = 1;
            atom[i].dependencies[0].atom_number = 0;
            atom[i].dependencies[1].atom_number = 0;
        }
        atom[2].size =
            reinterpret_cast<uintptr_t>(&atom[1]) - reinterpret_cast<uintptr_t>(&atom[2]);
        EXPECT_GE(atom[2].size, static_cast<uint64_t>(INT64_MAX));

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidZeroSize()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom;
        atom.size = 0;
        atom.atom_number = 1;
        atom.flags = 1;
        atom.dependencies[0].atom_number = 0;
        atom.dependencies[1].atom_number = 0;

        // Shouldn't infinite loop, for example.
        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidSmaller()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom;
        atom.size = sizeof(atom) - 1;
        atom.atom_number = 1;
        atom.flags = 1;
        atom.dependencies[0].atom_number = 0;
        atom.dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom) - 1, &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidInUse()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom[2];
        atom[0].size = sizeof(atom[0]);
        atom[0].atom_number = 0;
        atom[0].flags = 1;
        atom[0].dependencies[0].atom_number = 0;
        atom[0].dependencies[1].atom_number = 0;
        atom[1].size = sizeof(atom[1]);
        atom[1].atom_number = 0;
        atom[1].flags = 1;
        atom[1].dependencies[0].atom_number = 0;
        atom[1].dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        // There's no device thread, so the atoms shouldn't be able to complete.
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidDependencyNotSubmitted()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom;
        atom.size = sizeof(atom);
        atom.atom_number = 1;
        atom.flags = 1;
        // Can't depend on self or on later atoms.
        atom.dependencies[0].atom_number = 1;
        atom.dependencies[0].type = kArmMaliDependencyOrder;
        atom.dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidDependencyType()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom[2];
        atom[0].size = sizeof(atom[0]);
        atom[0].atom_number = 1;
        atom[0].flags = 1;
        atom[0].dependencies[0].atom_number = 0;
        atom[0].dependencies[1].atom_number = 0;
        atom[1].size = sizeof(atom[1]);
        atom[1].atom_number = 2;
        atom[1].flags = 1;
        atom[1].dependencies[0].atom_number = 1;
        atom[1].dependencies[0].type = 5;
        atom[1].dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestInvalidSemaphoreImmediate()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);

        magma_arm_mali_atom atom;
        atom.size = sizeof(atom);
        atom.atom_number = 0;
        atom.flags = kAtomFlagSemaphoreSet;
        atom.dependencies[0].atom_number = 0;
        atom.dependencies[1].atom_number = 0;

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 0, nullptr);
        EXPECT_EQ(MAGMA_STATUS_CONTEXT_KILLED, status.get());
    }

    void TestSemaphoreImmediate()
    {
        auto ctx = InitializeContext();
        ASSERT_TRUE(ctx);
        auto platform_semaphore = magma::PlatformSemaphore::Create();
        uint32_t handle;
        platform_semaphore->duplicate_handle(&handle);
        connection_->ImportObject(handle, magma::PlatformObject::SEMAPHORE);

        magma_arm_mali_atom atom;
        atom.size = sizeof(atom);
        atom.atom_number = 0;
        atom.flags = kAtomFlagSemaphoreSet;
        atom.dependencies[0].atom_number = 0;
        atom.dependencies[1].atom_number = 0;
        uint64_t semaphores[] = {platform_semaphore->id()};

        magma::Status status = ctx->ExecuteImmediateCommands(sizeof(atom), &atom, 1, semaphores);
        EXPECT_EQ(MAGMA_STATUS_OK, status.get());
    }

private:
    MagmaSystemContext* InitializeContext()
    {
        msd_drv_ = msd_driver_unique_ptr_t(msd_driver_create(), &msd_driver_destroy);
        if (!msd_drv_)
            return DRETP(nullptr, "failed to create msd driver");

        msd_driver_configure(msd_drv_.get(), MSD_DRIVER_CONFIG_TEST_NO_DEVICE_THREAD);

        platform_device_ = TestPlatformDevice::GetInstance();
        if (!platform_device_)
            DLOG("TestCommandBuffer: No platform device");
        auto msd_dev = msd_driver_create_device(
            msd_drv_.get(), platform_device_ ? platform_device_->GetDeviceHandle() : nullptr);
        if (!msd_dev)
            return DRETP(nullptr, "failed to create msd device");
        system_dev_ = std::shared_ptr<MagmaSystemDevice>(
            MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev)));
        uint32_t ctx_id = 0;
        auto msd_connection_t = msd_device_open(msd_dev, 0);
        if (!msd_connection_t)
            return DRETP(nullptr, "msd_device_open failed");
        connection_ = std::unique_ptr<MagmaSystemConnection>(
            new MagmaSystemConnection(system_dev_, MsdConnectionUniquePtr(msd_connection_t)));
        if (!connection_)
            return DRETP(nullptr, "failed to connect to msd device");
        connection_->CreateContext(ctx_id);
        auto ctx = connection_->LookupContext(ctx_id);
        if (!ctx)
            return DRETP(nullptr, "failed to create context");
        return ctx;
    }

    msd_driver_unique_ptr_t msd_drv_;
    magma::PlatformDevice* platform_device_;
    std::shared_ptr<MagmaSystemDevice> system_dev_;
    std::unique_ptr<MagmaSystemConnection> connection_;
};

TEST(CommandBuffer, TestInvalidSemaphoreImmediate) { ::Test().TestInvalidSemaphoreImmediate(); }
TEST(CommandBuffer, TestSemaphoreImmediate) { ::Test().TestSemaphoreImmediate(); }
TEST(CommandBuffer, TestValidImmediate) { ::Test().TestValidImmediate(); }
TEST(CommandBuffer, TestValidLarger) { ::Test().TestValidLarger(); }
TEST(CommandBuffer, TestInvalidTooLarge) { ::Test().TestInvalidTooLarge(); }
TEST(CommandBuffer, TestInvalidOverflow) { ::Test().TestInvalidOverflow(); }
TEST(CommandBuffer, TestInvalidZeroSize) { ::Test().TestInvalidZeroSize(); }
TEST(CommandBuffer, TestInvalidSmaller) { ::Test().TestInvalidSmaller(); }
TEST(CommandBuffer, TestInvalidInUse) { ::Test().TestInvalidInUse(); }
TEST(CommandBuffer, TestInvalidDependencyType) { ::Test().TestInvalidDependencyType(); }
TEST(CommandBuffer, TestInvalidDependencyNotSubmitted)
{
    ::Test().TestInvalidDependencyNotSubmitted();
}
} // namespace
