#!/usr/bin/python
#
# 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
from datetime import date

import registry_xml

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

#include "libANGLE/gl_enum_utils_autogen.h"

#include "libANGLE/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.iteritems():
        string_value_pairs = list(
            filter(lambda x: x[0] in exporting_enums, inner_mapping.iteritems()))
        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",
        year=date.today().year,
        gl_enum_groups=',\n'.join(sorted(gl_enum_in_groups.iterkeys())))

    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",
        year=date.today().year,
        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/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])))
