#!/usr/bin/python3
#
# Copyright 2019 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_gl_enum_utils.py:
#   Generates GLenum value to string mapping for ANGLE
#   NOTE: don't run this script directly. Run scripts/run_code_generation.py.

import sys
import os

import registry_xml

template_gl_enums_header = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright 2019 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.
//
// gl_enum_utils_autogen.h:
//   mapping of GLenum value to string.

# ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
# define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_

namespace gl
{{
enum class GLenumGroup
{{
    {gl_enum_groups}
}};
}}  // namespace gl

# endif  // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
"""

template_gl_enums_source = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright 2019 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.
//
// gl_enum_utils_autogen.cpp:
//   mapping of GLenum value to string.

#include "libANGLE/capture/gl_enum_utils_autogen.h"

#include "libANGLE/capture/gl_enum_utils.h"

namespace gl
{{
namespace
{{
const char *UnknownGLenumToString(unsigned int value)
{{
    constexpr size_t kBufferSize = 64;
    static thread_local char sBuffer[kBufferSize];
    snprintf(sBuffer, kBufferSize, "0x%04X", value);
    return sBuffer;
}}
}}  // anonymous namespace

const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)
{{
    switch (enumGroup)
    {{
        {gl_enums_value_to_string_table}
        default:
            return UnknownGLenumToString(value);
    }}
}}
}}  // namespace gl

"""

template_enum_group_case = """case GLenumGroup::{group_name}: {{
    switch (value) {{
        {inner_group_cases}
        default:
            return UnknownGLenumToString(value);
    }}
}}
"""

template_enum_value_to_string_case = """case {value}: return {name};"""

exclude_gl_enums = {
    'GL_NO_ERROR', 'GL_TIMEOUT_IGNORED', 'GL_INVALID_INDEX', 'GL_VERSION_ES_CL_1_0',
    'GL_VERSION_ES_CM_1_1', 'GL_VERSION_ES_CL_1_1'
}
exclude_gl_enum_groups = {'SpecialNumbers'}


def dump_value_to_string_mapping(gl_enum_in_groups, exporting_enums):
    exporting_groups = list()
    for group_name, inner_mapping in gl_enum_in_groups.items():
        string_value_pairs = list(filter(lambda x: x[0] in exporting_enums, inner_mapping.items()))
        if not string_value_pairs:
            continue

        # sort according values
        string_value_pairs.sort(key=lambda x: (x[1], x[0]))

        # remove all duplicate values from the pairs list
        # some value may have more than one GLenum mapped to them, such as:
        #     GL_DRAW_FRAMEBUFFER_BINDING and GL_FRAMEBUFFER_BINDING
        #     GL_BLEND_EQUATION_RGB and GL_BLEND_EQUATION
        # it is safe to output either one of them, for simplity here just
        # choose the shorter one which comes first in the sorted list
        exporting_string_value_pairs = list()
        for index, pair in enumerate(string_value_pairs):
            if index == 0 or pair[1] != string_value_pairs[index - 1][1]:
                exporting_string_value_pairs.append(pair)

        inner_code_block = "\n".join([
            template_enum_value_to_string_case.format(
                value='0x%X' % value,
                name='"%s"' % name,
            ) for name, value in exporting_string_value_pairs
        ])

        exporting_groups.append((group_name, inner_code_block))

    return "\n".join([
        template_enum_group_case.format(
            group_name=group_name,
            inner_group_cases=inner_code_block,
        ) for group_name, inner_code_block in sorted(exporting_groups, key=lambda x: x[0])
    ])


def main(header_output_path, source_output_path):
    xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')

    # build a map from GLenum name to its value
    all_gl_enums = dict()
    for enums_node in xml.root.findall('enums'):
        for enum in enums_node.findall('enum'):
            name = enum.attrib['name']
            value = int(enum.attrib['value'], base=16)
            all_gl_enums[name] = value

    # Parse groups of GLenums to build a {group, name} -> value mapping.
    gl_enum_in_groups = dict()
    enums_has_group = set()
    for enums_group_node in xml.root.findall('groups/group'):
        group_name = enums_group_node.attrib['name']
        if group_name in exclude_gl_enum_groups:
            continue

        if group_name not in gl_enum_in_groups:
            gl_enum_in_groups[group_name] = dict()

        for enum_node in enums_group_node.findall('enum'):
            enum_name = enum_node.attrib['name']
            enums_has_group.add(enum_name)
            gl_enum_in_groups[group_name][enum_name] = all_gl_enums[enum_name]

    # Find relevant GLenums according to enabled APIs and extensions.
    exporting_enums = set()
    # export all the apis
    xpath = "./feature[@api='gles2']/require/enum"
    for enum_tag in xml.root.findall(xpath):
        enum_name = enum_tag.attrib['name']
        if enum_name not in exclude_gl_enums:
            exporting_enums.add(enum_name)

    for extension in registry_xml.supported_extensions:
        xpath = "./extensions/extension[@name='%s']/require/enum" % extension
        for enum_tag in xml.root.findall(xpath):
            enum_name = enum_tag.attrib['name']
            if enum_name not in exclude_gl_enums:
                exporting_enums.add(enum_name)

    # For enums that do not have a group, add them to a default group
    default_group_name = registry_xml.default_enum_group_name
    gl_enum_in_groups[default_group_name] = dict()
    default_group = gl_enum_in_groups[default_group_name]
    for enum_name in exporting_enums:
        if enum_name not in enums_has_group:
            default_group[enum_name] = all_gl_enums[enum_name]

    # Write GLenum groups into the header file.
    header_content = template_gl_enums_header.format(
        script_name=os.path.basename(sys.argv[0]),
        data_source_name="gl.xml and gl_angle_ext.xml",
        gl_enum_groups=',\n'.join(sorted(gl_enum_in_groups.keys())))

    header_output_path = registry_xml.script_relative(header_output_path)
    with open(header_output_path, 'w') as f:
        f.write(header_content)

    # Write mapping to source file
    gl_enums_value_to_string_table = dump_value_to_string_mapping(gl_enum_in_groups,
                                                                  exporting_enums)
    source_content = template_gl_enums_source.format(
        script_name=os.path.basename(sys.argv[0]),
        data_source_name="gl.xml and gl_angle_ext.xml",
        gl_enums_value_to_string_table=gl_enums_value_to_string_table,
    )

    source_output_path = registry_xml.script_relative(source_output_path)
    with open(source_output_path, 'w') as f:
        f.write(source_content)

    return 0


if __name__ == '__main__':
    inputs = [
        'gl.xml',
        'gl_angle_ext.xml',
        'registry_xml.py',
    ]

    gl_enum_utils_autogen_base_path = '../src/libANGLE/capture/gl_enum_utils_autogen'
    outputs = [
        gl_enum_utils_autogen_base_path + '.h',
        gl_enum_utils_autogen_base_path + '.cpp',
    ]

    if len(sys.argv) > 1:
        if sys.argv[1] == 'inputs':
            print(','.join(inputs))
        elif sys.argv[1] == 'outputs':
            print(','.join(outputs))
    else:
        sys.exit(
            main(
                registry_xml.script_relative(outputs[0]),
                registry_xml.script_relative(outputs[1])))
