#!python
# Copyright 2017 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.
#
# gen_proc_table.py:
#  Code generation for entry point loading tables.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

# TODO(jmadill): Should be part of entry point generation.

import sys
from datetime import date
sys.path.append('../../scripts')
import registry_xml

out_file_name = "proc_table_autogen.cpp"

# The EGL_ANGLE_explicit_context extension is generated differently from other extensions.
# Toggle generation here.
support_egl_ANGLE_explicit_context = True

template_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} 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.
//
// getProcAddress loader table:
//   Mapping from a string entry point name to function address.
//

#include "libGLESv2/proc_table.h"

#include "libGLESv2/entry_points_egl.h"
#include "libGLESv2/entry_points_egl_ext.h"
#include "libGLESv2/entry_points_gles_1_0_autogen.h"
#include "libGLESv2/entry_points_gles_2_0_autogen.h"
#include "libGLESv2/entry_points_gles_3_0_autogen.h"
#include "libGLESv2/entry_points_gles_3_1_autogen.h"
#include "libGLESv2/entry_points_gles_ext_autogen.h"
#include "platform/Platform.h"

#define P(FUNC) reinterpret_cast<__eglMustCastToProperFunctionPointerType>(FUNC)

namespace egl
{{
ProcEntry g_procTable[] = {{
{proc_data}
}};

size_t g_numProcs = {num_procs};
}}  // namespace egl
"""

sys.path.append('../libANGLE/renderer')
import angle_format


def main():

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['../../scripts/' + source for source in registry_xml.xml_inputs]
        outputs = [out_file_name]
        if sys.argv[1] == 'inputs':
            print ','.join(inputs)
        elif sys.argv[1] == 'outputs':
            print ','.join(outputs)
        else:
            print('Invalid script parameters')
            return 1
        return 0

    glxml = registry_xml.RegistryXML('../../scripts/gl.xml', '../../scripts/gl_angle_ext.xml')

    for annotation in ["2_0", "3_0", "3_1", "1_0"]:

        name_prefix = "GL_ES_VERSION_"
        if annotation[0] == '1':
            name_prefix = "GL_VERSION_ES_CM_"
        feature_name = "{}{}".format(name_prefix, annotation)

        glxml.AddCommands(feature_name, annotation)

    glxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1'])

    data = glxml.all_cmd_names.get_all_commands()

    eglxml = registry_xml.RegistryXML('../../scripts/egl.xml', '../../scripts/egl_angle_ext.xml')

    for annotation in ["1_0", "1_1", "1_2", "1_3", "1_4", "1_5"]:

        name_prefix = "EGL_VERSION_"
        feature_name = "{}{}".format(name_prefix, annotation)

        eglxml.AddCommands(feature_name, annotation)

    eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1'])

    data.extend(eglxml.all_cmd_names.get_all_commands())

    data.append("ANGLEGetDisplayPlatform")
    data.append("ANGLEResetDisplayPlatform")

    all_functions = {}

    for function in data:
        if function.startswith("gl"):
            all_functions[function] = "gl::" + function[2:]
            # Special handling for EGL_ANGLE_explicit_context extension
            if support_egl_ANGLE_explicit_context:
                all_functions[function + "ContextANGLE"] = "gl::" + function[2:] + "ContextANGLE"
        elif function.startswith("egl"):
            all_functions[function] = "EGL_" + function[3:]
        else:
            all_functions[function] = function

    proc_data = [('    {"%s", P(%s)}' % (func, angle_func))
                 for func, angle_func in sorted(all_functions.iteritems())]

    with open(out_file_name, 'w') as out_file:
        output_cpp = template_cpp.format(
            script_name=sys.argv[0],
            data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml",
            copyright_year=date.today().year,
            proc_data=",\n".join(proc_data),
            num_procs=len(proc_data))
        out_file.write(output_cpp)
        out_file.close()
    return 0


if __name__ == '__main__':
    sys.exit(main())
