#!/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}
}};
}}  // 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);
    }}
}}

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()
    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'])

    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'])

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

    # Add all enums to default groups
    gles_default_enums = dict()
    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 '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

    for empty_group in empty_enum_groups:
        assert empty_group not in gles_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()

    # 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())))

    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')
    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,
        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])))
