#!/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"

#include <sstream>

#include "common/bitset_utils.h"

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


std::string GLbitfieldToString(GLenumGroup enumGroup, unsigned int value)
{{
    std::stringstream st;

    const angle::BitSet<32> bitSet(value);
    bool first = true;
    for (const auto index : bitSet)
    {{
        if (!first)
        {{
            st << " | ";
        }}
        first = false;

        unsigned int mask = 1u << index;
        OutputGLenumString(st, enumGroup, mask);
    }}

    return st.str();
}}
}}  // namespace gl

"""

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

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