/*
 * Copyright 2024 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/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/gpu/ganesh/gl/GrGLDirectContext.h"
#include "include/gpu/gl/GrGLInterface.h"
#include "include/encode/SkWebpEncoder.h"

#if defined(__linux__)
#include "include/gpu/ganesh/gl/glx/GrGLMakeGLXInterface.h"

#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#endif

#if defined(__APPLE__) && TARGET_OS_MAC == 1
#include "include/gpu/ganesh/gl/mac/GrGLMakeMacInterface.h"

#include "gl_context_helper.h"
#endif

#include <cstdio>

#if defined(__linux__)

// Set up an X Display that can be rendered to GL. This will not be visible while
// the program runs. It is cribbed from how Skia's tooling sets itself up (e.g. viewer).
bool initialize_gl_linux() {
    Display* display = XOpenDisplay(nullptr);
    if (!display) {
        printf("Could not open an X display\n");
        return false;
    }
    static int constexpr kChooseFBConfigAtt[] = {
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_DOUBLEBUFFER, True,
        GLX_STENCIL_SIZE, 8,
        None
    };
    int n;
    GLXFBConfig* fbConfig = glXChooseFBConfig(display, DefaultScreen(display), kChooseFBConfigAtt, &n);
    XVisualInfo* visualInfo;
    if (n > 0) {
        visualInfo = glXGetVisualFromFBConfig(display, *fbConfig);
    } else {
        // For some reason glXChooseVisual takes a non-const pointer to the attributes.
        int chooseVisualAtt[] = {
            GLX_RGBA,
            GLX_DOUBLEBUFFER,
            GLX_STENCIL_SIZE, 8,
            None
        };
        visualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
    }
    if (!visualInfo) {
        printf("Could not get X visualInfo\n");
        return false;
    }
    GLXContext glContext = glXCreateContext(display, visualInfo, nullptr, GL_TRUE);
    if (!glContext) {
        printf("Could not make GL X context\n");
        return false;
    }
    Colormap colorMap = XCreateColormap(display,
                                        RootWindow(display, visualInfo->screen),
                                        visualInfo->visual,
                                        AllocNone);
    XSetWindowAttributes swa;
    swa.colormap = colorMap;
    swa.event_mask = 0;
    Window window = XCreateWindow(display,
                            RootWindow(display, visualInfo->screen),
                            0, 0, // x, y
                            1280, 960, // width, height
                            0, // border width
                            visualInfo->depth,
                            InputOutput,
                            visualInfo->visual,
                            CWEventMask | CWColormap,
                            &swa);

    if (!glXMakeCurrent(display, window, glContext)) {
        printf("Could not set GL X context to be the created one\n");
        return false;
    }
    return true;
}
#endif  // defined(__linux__)

int main(int argc, char** argv) {
    if (argc != 2) {
        printf("Usage: %s <name.webp>\n", argv[0]);
        return 1;
    }

    SkFILEWStream output(argv[1]);
    if (!output.isValid()) {
        printf("Cannot open output file %s\n", argv[1]);
        return 1;
    }

    GrContextOptions opts;
    opts.fSuppressPrints = true;
#if defined(__linux__)
    if (!initialize_gl_linux()) {
        return 1;
    }
    sk_sp<const GrGLInterface> interface = GrGLInterfaces::MakeGLX();
#elif defined(__APPLE__) && TARGET_OS_MAC == 1
    if (!initialize_gl_mac()) {
        return 1;
    }
    sk_sp<const GrGLInterface> interface = GrGLInterfaces::MakeMac();
#endif
    if (!interface) {
        printf("Could not make GL interface\n");
        return 1;
    }

    sk_sp<GrDirectContext> ctx = GrDirectContexts::MakeGL(interface, opts);
    if (!ctx) {
        printf("Could not make GrDirectContext\n");
        return 1;
    }
    printf("Context made, now to make the surface\n");

    SkImageInfo imageInfo =
            SkImageInfo::Make(200, 400, kRGBA_8888_SkColorType, kPremul_SkAlphaType);

    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(ctx.get(), skgpu::Budgeted::kYes, imageInfo);
    if (!surface) {
        printf("Could not make surface from GL DirectContext\n");
        return 1;
    }

    SkCanvas* canvas = surface->getCanvas();
    canvas->clear(SK_ColorRED);
    SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(10, 20, 50, 70), 10, 10);

    SkPaint paint;
    paint.setColor(SK_ColorBLUE);
    paint.setAntiAlias(true);

    canvas->drawRRect(rrect, paint);

    ctx->flush();

    printf("Drew to surface, now doing readback\n");
    sk_sp<SkImage> img = surface->makeImageSnapshot();
    sk_sp<SkData> webp = SkWebpEncoder::Encode(ctx.get(), img.get(), {});
    if (!webp) {
        printf("Readback of pixels (or encoding) failed\n");
        return 1;
    }
    output.write(webp->data(), webp->size());
    output.fsync();

    return 0;
}
