#!/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 COMMON_GL_ENUM_UTILS_AUTOGEN_H_
# define COMMON_GL_ENUM_UTILS_AUTOGEN_H_

namespace gl
{{
enum class GLESEnum
{{
    {gles_enum_groups}
}};

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

# endif  // COMMON_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 "common/gl_enum_utils_autogen.h"

#include "common/debug.h"
#include "common/gl_enum_utils.h"

#include <algorithm>
#include <cstring>

namespace gl
{{
namespace
{{
const char *UnknownEnumToString(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(GLESEnum enumGroup, unsigned int value)
{{
    switch (enumGroup)
    {{
        {gles_enums_value_to_string_table}
        default:
            return UnknownEnumToString(value);
    }}
}}

const char *GLenumToString(BigGLEnum enumGroup, unsigned int value)
{{
    switch (enumGroup)
    {{
        {gl_enums_value_to_string_table}
        default:
            return UnknownEnumToString(value);
    }}
}}

namespace
{{
using StringEnumEntry = std::pair<const char*, unsigned int>;
static StringEnumEntry g_stringEnumTable[] = {{
    {string_to_enum_table}
}};

const size_t g_numStringEnums = std::size(g_stringEnumTable);
}}  // anonymous namespace

unsigned int StringToGLenum(const char *str)
{{
    auto it = std::lower_bound(
        &g_stringEnumTable[0], &g_stringEnumTable[g_numStringEnums], str,
        [](const StringEnumEntry& a, const char* b) {{ return strcmp(a.first, b) < 0; }});

    if (strcmp(it->first, str) == 0)
    {{
        return it->second;
    }}

    UNREACHABLE();
    return 0;
}}
}}  // namespace gl

"""

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

template_enum_value_to_string_case = """case {value}: return {name};"""
exclude_enum_groups = {'SpecialNumbers'}

# Special enum groups that don't have any enum values.
# Add groups here if you get missing group compile errors.
empty_enum_groups = ['SemaphoreParameterName', 'ShaderBinaryFormat']


def dump_value_to_string_mapping(enum_groups, api_enum):
    exporting_groups = list()
    for group_name, inner_mapping in enum_groups.items():
        # Convert to pairs and strip out-of-range values.
        string_value_pairs = list(
            filter(lambda x: x[1] >= 0 and x[1] <= 0xFFFFFFFFF, inner_mapping.items()))
        if not string_value_pairs:
            continue

        # sort according values
        string_value_pairs.sort(key=lambda x: (x[1], len(x[0]), 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(
            api_enum=api_enum,
            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 dump_string_to_value_mapping(enums_and_values):

    def f(value):
        if value < 0:
            return str(value)
        if value < 0xFFFF:
            return "0x%04X" % value
        if value <= 0xFFFFFFFF:
            return "0x%X" % value
        else:
            return "0xFFFFFFFF"

    return '\n'.join('{"%s", %s},' % (k, f(v)) for k, v in sorted(enums_and_values))


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

    # Compute a list of all GLES enums.
    gles_enums = set()
    bigl_enums = set()
    for feature in xml.root.findall('feature'):
        for require in feature.findall('require'):
            assert 'api' not in require.attrib
            if 'gles' in feature.attrib['api']:
                for enum in require.findall('enum'):
                    gles_enums.add(enum.attrib['name'])
            if feature.attrib['api'] == 'gl':
                for enum in require.findall('enum'):
                    bigl_enums.add(enum.attrib['name'])

    for extensions in xml.root.findall('extensions'):
        for extension in extensions.findall('extension'):
            if extension.attrib['name'] in registry_xml.supported_extensions:
                for require in extension.findall('require'):
                    ext_apis = extension.attrib['supported'].split('|')
                    if ('api' not in require.attrib or 'gles' in require.attrib['api']) and (
                            'gles' in extension.attrib['supported']):
                        for enum in require.findall('enum'):
                            gles_enums.add(enum.attrib['name'])
                    if ('api' not in require.attrib or
                            feature.attrib['api'] == 'gl') and ('gl' in ext_apis):
                        for enum in require.findall('enum'):
                            bigl_enums.add(enum.attrib['name'])

    # Build a map from GLenum name to its value
    gl_enum_groups = dict()
    gles_enum_groups = dict()

    # Add all enums to default groups
    gl_default_enums = dict()
    gles_default_enums = dict()
    gl_enum_groups[registry_xml.default_enum_group_name] = gl_default_enums
    gles_enum_groups[registry_xml.default_enum_group_name] = gles_default_enums
    enums_and_values = []

    for enums_node in xml.root.findall('enums'):
        for enum in enums_node.findall('enum'):
            enum_name = enum.attrib['name']
            enum_value = int(enum.attrib['value'], base=16)
            enums_and_values.append((enum_name, enum_value))

            if enum_name in gles_enums:
                gles_default_enums[enum_name] = enum_value
            if enum_name in bigl_enums:
                gl_default_enums[enum_name] = enum_value

            if 'group' in enum.attrib:
                for enum_group in enum.attrib['group'].split(','):
                    if enum_group in exclude_enum_groups:
                        continue
                    if enum_name in gles_enums:
                        if enum_group not in gles_enum_groups:
                            gles_enum_groups[enum_group] = dict()
                        gles_enum_groups[enum_group][enum_name] = enum_value
                    if enum_name in bigl_enums:
                        if enum_group not in gl_enum_groups:
                            gl_enum_groups[enum_group] = dict()
                        gl_enum_groups[enum_group][enum_name] = enum_value

    for empty_group in empty_enum_groups:
        assert not empty_group in gles_enum_groups or not empty_group in gl_enum_groups, 'Remove %s from the empty groups list, it has enums now.' % empty_group
        if empty_group not in gles_enum_groups:
            gles_enum_groups[empty_group] = dict()
        if empty_group not in gl_enum_groups:
            gl_enum_groups[empty_group] = dict()

    # 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",
        gles_enum_groups=',\n'.join(sorted(gles_enum_groups.keys())),
        gl_enum_groups=',\n'.join(sorted(gl_enum_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
    gles_enums_value_to_string_table = dump_value_to_string_mapping(gles_enum_groups, 'GLESEnum')
    gl_enums_value_to_string_table = dump_value_to_string_mapping(gl_enum_groups, 'BigGLEnum')
    string_to_enum_table = dump_string_to_value_mapping(enums_and_values)
    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",
        gles_enums_value_to_string_table=gles_enums_value_to_string_table,
        gl_enums_value_to_string_table=gl_enums_value_to_string_table,
        string_to_enum_table=string_to_enum_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 = [
        '../third_party/OpenGL-Registry/src/xml/gl.xml',
        'gl_angle_ext.xml',
        'registry_xml.py',
    ]

    gl_enum_utils_autogen_base_path = '../src/common/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])))
