/*
 * Copyright 2023 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/SkTypes.h"

#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "tools/ToolUtils.h"
#include "tools/viewer/Slide.h"

#if defined(SK_GANESH)
#include "include/android/SkImageAndroid.h"
#include "include/android/SkSurfaceAndroid.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#endif

#if defined(SK_GRAPHITE)
#include "include/android/graphite/SurfaceAndroid.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Surface.h"
#include "src/gpu/graphite/RecorderPriv.h"

#else
namespace skgpu::graphite {
    class Recorder;
}
#endif

#include <android/hardware_buffer.h>

using namespace skgpu::graphite;

namespace {

static void release_buffer(AHardwareBuffer* buffer) {
    if (buffer) {
        AHardwareBuffer_release(buffer);
    }
}

sk_sp<SkSurface> wrap_buffer(GrDirectContext* dContext,
                             Recorder* recorder,
                             AHardwareBuffer* buffer) {
#if defined(SK_GANESH)
    if (dContext) {
        return SkSurfaces::WrapAndroidHardwareBuffer(dContext,
                                                     buffer,
                                                     kTopLeft_GrSurfaceOrigin,
                                                     /* colorSpace= */ nullptr,
                                                     /* surfaceProps= */ nullptr);
    }
#endif

#if defined(SK_GRAPHITE)
    if (recorder) {
        return SkSurfaces::WrapAndroidHardwareBuffer(recorder,
                                                     buffer,
                                                     /* colorSpace= */ nullptr,
                                                     /* surfaceProps= */ nullptr);
    }
#endif

    return nullptr;
}

sk_sp<SkSurface> create_protected_render_target(GrDirectContext* dContext,
                                                Recorder* recorder,
                                                const SkImageInfo& ii) {
#if defined(SK_GANESH)
    if (dContext) {
        return SkSurfaces::RenderTarget(dContext,
                                        skgpu::Budgeted::kYes,
                                        ii,
                                        /* sampleCount= */ 1,
                                        kTopLeft_GrSurfaceOrigin,
                                        /* surfaceProps= */ nullptr,
                                        /* shouldCreateWithMips= */ false,
                                        /* isProtected= */ true);
    }
#endif

#if defined(SK_GRAPHITE)
    if (recorder) {
        // Protected-ness is pulled off of the recorder
        return SkSurfaces::RenderTarget(recorder,
                                        ii,
                                        skgpu::Mipmapped::kNo,
                                        /* props= */ nullptr);
    }
#endif

    return nullptr;
}

AHardwareBuffer* create_protected_buffer(int width, int height) {

    AHardwareBuffer* buffer = nullptr;

    AHardwareBuffer_Desc hwbDesc;
    hwbDesc.width = width;
    hwbDesc.height = height;
    hwbDesc.layers = 1;
    hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
                    AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
                    AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
                    AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;

    hwbDesc.usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;

    hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
    // The following three are not used in the allocate
    hwbDesc.stride = 0;
    hwbDesc.rfu0= 0;
    hwbDesc.rfu1= 0;

    if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
        SkDebugf("Failed to allocated hardware buffer, error: %d\n", error);
        release_buffer(buffer);
        return nullptr;
    }

    return buffer;
}

sk_sp<SkImage> create_protected_AHB_image(GrDirectContext* dContext,
                                          Recorder* recorder,
                                          AHardwareBuffer* buffer,
                                          SkColor color) {

    sk_sp<SkSurface> surf = wrap_buffer(dContext, recorder, buffer);
    if (!surf) {
        SkDebugf("Failed to make SkSurface.\n");
        return nullptr;
    }

    ToolUtils::draw_checkerboard(surf->getCanvas(), color, SK_ColorTRANSPARENT, 32);

    return surf->makeImageSnapshot();
}

sk_sp<SkImage> create_protected_skia_image(GrDirectContext* dContext,
                                           Recorder* recorder,
                                           int width, int height,
                                           SkColor color) {
    SkImageInfo ii = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
                                       kPremul_SkAlphaType);

    sk_sp<SkSurface> tmpSurface = create_protected_render_target(dContext, recorder, ii);
    if (!tmpSurface) {
        return nullptr;
    }

    ToolUtils::draw_checkerboard(tmpSurface->getCanvas(), color, SK_ColorTRANSPARENT, 32);

    return tmpSurface->makeImageSnapshot();
}

} // anonymous namespace

class ProtectedSlide : public Slide {
public:
    ProtectedSlide() { fName = "Protected"; }

    SkISize getDimensions() const override { return {kSize, 2*kSize}; }

    void draw(SkCanvas* origCanvas) override {
        origCanvas->clear(SK_ColorDKGRAY);

        skgpu::graphite::Recorder* recorder = origCanvas->recorder();
        GrDirectContext* dContext = GrAsDirectContext(origCanvas->recordingContext());

#if defined(SK_GANESH)
        if (dContext && !dContext->supportsProtectedContent()) {
            origCanvas->clear(SK_ColorGREEN);
            return;
        }
#endif

#if defined(SK_GRAPHITE)
        if (recorder && recorder->priv().isProtected() == skgpu::Protected::kNo) {
            origCanvas->clear(SK_ColorBLUE);
            return;
        }
#endif

        if (!dContext && !recorder) {
            origCanvas->clear(SK_ColorRED);
            return;
        }

        AHardwareBuffer* buffer = create_protected_buffer(kSize, kSize);

        sk_sp<SkImage> protectedAHBImage = create_protected_AHB_image(dContext, recorder, buffer,
                                                                      SK_ColorRED);
        sk_sp<SkImage> protectedSkImage = create_protected_skia_image(dContext, recorder,
                                                                      kSize, kSize, SK_ColorBLUE);

        // Pick one of the two protected images to draw. Only the protected AHB-backed image will
        // reproduce the bug (b/242266174).
        SkImage* imgToUse = protectedAHBImage.get();
//        SkImage* imgToUse = protectedSkImage.get();

        sk_sp<SkImage> indirectImg;

        {
            SkImageInfo ii = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
                                               kPremul_SkAlphaType);
            sk_sp<SkSurface> tmpS = create_protected_render_target(dContext, recorder, ii);

            tmpS->getCanvas()->clear(SK_ColorMAGENTA);
            tmpS->getCanvas()->drawCircle(64, 64, 32, SkPaint());

            // For protected AHB-backed images this draw seems to poison all above the draws too
            tmpS->getCanvas()->drawImage(imgToUse, 0, 0);
            indirectImg = tmpS->makeImageSnapshot();
        }

        origCanvas->drawImage(imgToUse, 0, 0);
        origCanvas->drawImage(indirectImg, 0, kSize);

        protectedAHBImage.reset();
        protectedSkImage.reset();
        release_buffer(buffer);
    }

private:
    static const int kSize = 128;
};

DEF_SLIDE( return new ProtectedSlide(); )

#endif
