//
// Copyright 2025 The ANGLE Project 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 "test_utils/ANGLETestCL.h"

#include <angle_cl.h>
#include "util/test_utils.h"

using namespace angle;

namespace
{

void CL_CALLBACK ContextCreated(const char *errinfo,
                                const void *private_info,
                                size_t cb,
                                void *user_data)
{
    std::cout << "Context created";
}

class CapturedTestCL : public ANGLETestCL<>
{
  protected:
    CapturedTestCL() : ANGLETestCL(this->GetParam()) {}
};

class MultiFrameCL
{
  public:
    MultiFrameCL() {}

    void testSetUp()
    {
        // Get platform
        cl_platform_id platform;
        clGetPlatformIDs(1, &platform, nullptr);

        // Get device
        cl_device_id device;
        clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr);

        // Create context
        context = clCreateContext(nullptr, 1, &device, ContextCreated, nullptr, nullptr);
        assert(context != nullptr);

        // Create command queue
        queue = clCreateCommandQueue(context, device, 0, nullptr);
        assert(queue != nullptr);

        // Create and build program
        const char *kernelSource = R"(
        __kernel void frame1(__global float *output)
        {
            int gid = get_global_id(0);
            output[gid] = gid * 2.0f;
        }

        __kernel void frame2(__global float *output)
        {
            int gid = get_global_id(0);
            output[gid] = gid * gid;
        }

        __kernel void frame3(__global float *output)
        {
            int gid = get_global_id(0);
            output[gid] = gid + 100.0f;
        }

        __kernel void frame4(__global float *output)
        {
            int gid = get_global_id(0);
            output[gid] = gid;
            if (gid == 0)
            {
                printf("Frame 4!\n");
            }
        }

        __kernel void frame5(__global float *output)
        {
            int gid = get_global_id(0);
            output[gid] = gid/gid;
        }
        )";
        program = clCreateProgramWithSource(context, 1, &kernelSource, nullptr, nullptr);
        clBuildProgram(program, 0, nullptr, nullptr, nullptr, nullptr);

        cl_build_status status;
        clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status),
                              &status, nullptr);
        std::cout << "Build status: " << status << "\n";
    }

    void testTearDown()
    {
        clReleaseProgram(program);
        clReleaseCommandQueue(queue);
        clReleaseContext(context);
    }

    void frame1() { executeKernel("frame1"); }

    void frame2() { executeKernel("frame2"); }

    void frame3() { executeKernel("frame3"); }

    void frame4() { executeKernel("frame4"); }

    void frame5() { executeKernel("frame5"); }

  private:
    void executeKernel(const char *kernelName)
    {

        // Create buffer
        outputBuffer =
            clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * 128, nullptr, nullptr);

        // Get CL_MEM_SIZE
        size_t memSize;
        clGetMemObjectInfo(outputBuffer, CL_MEM_SIZE, sizeof(size_t), &memSize, nullptr);
        std::cout << "Buffer size: " << memSize << ":\n";

        // Create kernel
        cl_kernel kernel = clCreateKernel(program, kernelName, nullptr);
        assert(kernel != nullptr);

        // Set kernel arguments
        clSetKernelArg(kernel, 0, sizeof(cl_mem), &outputBuffer);

        // Execute kernel
        size_t globalWorkSize = 128;
        clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &globalWorkSize, nullptr, 0, nullptr,
                               nullptr);

        // Read and verify results
        std::vector<float> results(128);
        clEnqueueReadBuffer(queue, outputBuffer, CL_TRUE, 0, sizeof(float) * 128, results.data(), 0,
                            nullptr, nullptr);

        // Print the results
        std::cout << "Results from " << kernelName << ":\n";
        for (size_t i = 0; i < results.size(); ++i)
        {
            std::cout << results[i] << " ";
        }
        std::cout << "\n";

        // Cleanup kernel
        clReleaseKernel(kernel);

        // Cleanup buffer
        clReleaseMemObject(outputBuffer);
    }

    cl_context context;
    cl_command_queue queue;
    cl_program program;
    cl_mem outputBuffer;
};

// OpenCL test captured by capture_tests.py
TEST_P(CapturedTestCL, MultiFrameCL)
{
    MultiFrameCL test;
    test.testSetUp();

    // Execute multiple frames
    test.frame1();
    test.frame2();
    test.frame3();
    test.frame4();
    test.frame5();

    test.testTearDown();
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CapturedTestCL);
// Capture is only supported on the Vulkan backend
ANGLE_INSTANTIATE_TEST(CapturedTestCL, ES3_VULKAN());
}  // anonymous namespace