/*
 * Copyright 2025-2025 Huawei Technologies Co., Ltd. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

#ifdef SK_BUILD_FOR_OHOS

#include "include/gpu/ganesh/gl/GrGLAssembleInterface.h"
#include "include/gpu/ganesh/gl/GrGLInterface.h"
#include "include/gpu/ganesh/gl/GrGLExtensions.h"
#include "src/gpu/ganesh/gl/GrGLCoreFunctions.h"
#include "src/gpu/ganesh/gl/GrGLUtil.h"

#include <cstring>
#include <dlfcn.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>

static GrGLFuncPtr ohos_get_gl_proc(void* ctx, const char name[])
{
    (void)ctx;

    if (!name) {
        return nullptr;
    }

    // Prefer EGL for extensions, but fall back to dlsym for core GLES symbols.
    // This keeps core entry points like glGetString available even when
    // eglGetProcAddress only resolves extensions.
    GrGLFuncPtr proc = eglGetProcAddress(name);
    if (proc) {
        return proc;
    }

    return reinterpret_cast<GrGLFuncPtr>(dlsym(RTLD_DEFAULT, name));
}

sk_sp<const GrGLInterface> GrGLMakeNativeInterface_OHOS()
{
    sk_sp<const GrGLInterface> interface = GrGLMakeAssembledInterface(nullptr, ohos_get_gl_proc);
    if (!interface) {
        return nullptr;
    }
    
    // Initialize GL extensions - this is CRITICAL for validation
    // We need to cast away const to initialize extensions
    GrGLInterface* mutableInterface = const_cast<GrGLInterface*>(interface.get());
    
    if (!mutableInterface->fExtensions.isInitialized()) {
        if (!mutableInterface->fExtensions.init(
            mutableInterface->fStandard,
            mutableInterface->fFunctions.fGetString,
            mutableInterface->fFunctions.fGetStringi,
            mutableInterface->fFunctions.fGetIntegerv)) {
            return nullptr;
        }
    }
    
    return interface;
}

#endif  // SK_BUILD_FOR_OHOS

