/*
 * Copyright 2026 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkSurface.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "tests/Test.h"
#include "tools/graphite/GraphiteTestContext.h"

using namespace skgpu::graphite;

namespace {

struct FinishContext {
    skiatest::Reporter* fReporter;
    bool fCalled = false;
};

void FinishProc(GpuFinishedContext ctx, skgpu::CallbackResult result) {
    FinishContext* fc = static_cast<FinishContext*>(ctx);
    REPORTER_ASSERT(fc->fReporter, result == skgpu::CallbackResult::kSuccess);
    fc->fCalled = true;
}

}  // anonymous namespace

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(SubmitWithFinishProc_PendingCommandBuffer,
                                               reporter,
                                               context,
                                               testCtx,
                                               /*condition=*/true,
                                               CtsEnforcement::kApiLevel_202604) {
    // Ensure the Context is fully idle initially.
    testCtx->syncedSubmit(context);

    std::unique_ptr<Recorder> recorder = context->makeRecorder();
    SkImageInfo ii = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    auto surface = SkSurfaces::RenderTarget(recorder.get(), ii);
    if (!surface) {
        ERRORF(reporter, "Failed to create surface");
        return;
    }
    surface->getCanvas()->clear(SkColors::kRed);

    FinishContext recordingFinishContext;
    recordingFinishContext.fReporter = reporter;

    // Add work to the pending command buffer with a finish proc on the recording.
    auto recording = recorder->snap();
    InsertRecordingInfo info;
    info.fRecording = recording.get();
    info.fFinishedProc = FinishProc;
    info.fFinishedContext = &recordingFinishContext;
    context->insertRecording(info);

    FinishContext submitFinishContext;
    submitFinishContext.fReporter = reporter;

    // Submit the pending command buffer with a finish proc attached.
    SubmitInfo submitInfo;
    submitInfo.fFinishedProc = FinishProc;
    submitInfo.fFinishedContext = &submitFinishContext;
    context->submit(submitInfo);

    // Syncing should trigger both callbacks.
    testCtx->syncedSubmit(context);
    REPORTER_ASSERT(reporter, recordingFinishContext.fCalled);
    REPORTER_ASSERT(reporter, submitFinishContext.fCalled);
}

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(SubmitWithFinishProc_NoPendingCommandBuffer,
                                               reporter,
                                               context,
                                               testCtx,
                                               /*condition=*/true,
                                               CtsEnforcement::kApiLevel_202604) {
    // Ensure the Context is fully idle.
    testCtx->syncedSubmit(context);

    FinishContext finishContext;
    finishContext.fReporter = reporter;

    // No pending command buffer and GPU is idle: the proc should be triggered immediately.
    SubmitInfo submitInfo;
    submitInfo.fFinishedProc = FinishProc;
    submitInfo.fFinishedContext = &finishContext;
    context->submit(submitInfo);

    REPORTER_ASSERT(reporter, finishContext.fCalled);
}
