# encoding=utf-8
# Copyright © 2017 Intel Corporation

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""Create enum to string functions for vulkan using vk.xml."""

from __future__ import print_function
import argparse
import os
import textwrap
import xml.etree.ElementTree as et

from mako.template import Template

COPYRIGHT = textwrap.dedent(u"""\
    * Copyright © 2017 Intel Corporation
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.""")

C_TEMPLATE = Template(textwrap.dedent(u"""\
    /* Autogenerated file -- do not edit
     * generated by ${file}
     *
     ${copyright}
     */

    #include <string.h>
    #include <vulkan/vulkan.h>
    #include <vulkan/vk_android_native_buffer.h>
    #include <vulkan/vk_layer.h>
    #include "util/macros.h"
    #include "vk_enum_to_str.h"

    % for enum in enums:

      % if enum.guard:
#ifdef ${enum.guard}
      % endif
    const char *
    vk_${enum.name[2:]}_to_str(${enum.name} input)
    {
        switch(input) {
    % for v in sorted(enum.values.keys()):
        case ${v}:
            return "${enum.values[v]}";
    % endfor
        default:
            unreachable("Undefined enum value.");
        }
    }

      % if enum.guard:
#endif
      % endif
    %endfor

    size_t vk_structure_type_size(const struct VkBaseInStructure *item)
    {
        switch((int)item->sType) {
    % for struct in structs:
        % if struct.extension is not None and struct.extension.define is not None:
    #ifdef ${struct.extension.define}
        case ${struct.stype}: return sizeof(${struct.name});
    #endif
        % else:
        case ${struct.stype}: return sizeof(${struct.name});
        % endif
    %endfor
        case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO: return sizeof(VkLayerInstanceCreateInfo);
        case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO: return sizeof(VkLayerDeviceCreateInfo);
        default:
            unreachable("Undefined struct type.");
        }
    }
    """),
    output_encoding='utf-8')

H_TEMPLATE = Template(textwrap.dedent(u"""\
    /* Autogenerated file -- do not edit
     * generated by ${file}
     *
     ${copyright}
     */

    #ifndef MESA_VK_ENUM_TO_STR_H
    #define MESA_VK_ENUM_TO_STR_H

    #include <vulkan/vulkan.h>
    #include <vulkan/vk_android_native_buffer.h>

    #ifdef __cplusplus
    extern "C" {
    #endif

    % for ext in extensions:
    #define _${ext.name}_number (${ext.number})
    % endfor

    % for enum in enums:
      % if enum.guard:
#ifdef ${enum.guard}
      % endif
    const char * vk_${enum.name[2:]}_to_str(${enum.name} input);
      % if enum.guard:
#endif
      % endif
    % endfor

    size_t vk_structure_type_size(const struct VkBaseInStructure *item);

    #ifdef __cplusplus
    } /* extern "C" */
    #endif

    #endif"""),
    output_encoding='utf-8')


class NamedFactory(object):
    """Factory for creating enums."""

    def __init__(self, type_):
        self.registry = {}
        self.type = type_

    def __call__(self, name, **kwargs):
        try:
            return self.registry[name]
        except KeyError:
            n = self.registry[name] = self.type(name, **kwargs)
        return n

    def get(self, name):
        return self.registry.get(name)


class VkExtension(object):
    """Simple struct-like class representing extensions"""

    def __init__(self, name, number=None, define=None):
        self.name = name
        self.number = number
        self.define = define


class VkEnum(object):
    """Simple struct-like class representing a single Vulkan Enum."""

    def __init__(self, name, values=None):
        self.name = name
        self.extension = None
        # Maps numbers to names
        self.values = values or dict()
        self.name_to_value = dict()
        self.guard = None
        self.name_to_alias_list = {}

    def add_value(self, name, value=None,
                  extnum=None, offset=None, alias=None,
                  error=False):
        if alias is not None:
            assert value is None and offset is None
            if alias not in self.name_to_value:
                # We don't have this alias yet.  Just record the alias and
                # we'll deal with it later.
                alias_list = self.name_to_alias_list.get(alias, [])
                alias_list.append(name);
                return

            # Use the value from the alias
            value = self.name_to_value[alias]

        assert value is not None or extnum is not None
        if value is None:
            value = 1000000000 + (extnum - 1) * 1000 + offset
            if error:
                value = -value

        self.name_to_value[name] = value
        if value not in self.values:
            self.values[value] = name
        elif len(self.values[value]) > len(name):
            self.values[value] = name

        # Now that the value has been fully added, resolve aliases, if any.
        if name in self.name_to_alias_list:
            for alias in self.name_to_alias_list[name]:
                add_value(alias, value)
            del self.name_to_alias_list[name]

    def add_value_from_xml(self, elem, extension=None):
        self.extension = extension
        if 'value' in elem.attrib:
            self.add_value(elem.attrib['name'],
                           value=int(elem.attrib['value'], base=0))
        elif 'alias' in elem.attrib:
            self.add_value(elem.attrib['name'], alias=elem.attrib['alias'])
        else:
            error = 'dir' in elem.attrib and elem.attrib['dir'] == '-'
            if 'extnumber' in elem.attrib:
                extnum = int(elem.attrib['extnumber'])
            else:
                extnum = extension.number
            self.add_value(elem.attrib['name'],
                           extnum=extnum,
                           offset=int(elem.attrib['offset']),
                           error=error)

    def set_guard(self, g):
        self.guard = g


class VkCommand(object):
    """Simple struct-like class representing a single Vulkan command"""

    def __init__(self, name, device_entrypoint=False):
        self.name = name
        self.device_entrypoint = device_entrypoint
        self.extension = None


class VkChainStruct(object):
    """Simple struct-like class representing a single Vulkan struct identified with a VkStructureType"""
    def __init__(self, name, stype):
        self.name = name
        self.stype = stype
        self.extension = None


def struct_get_stype(xml_node):
    for member in xml_node.findall('./member'):
        name = member.findall('./name')
        if len(name) > 0 and name[0].text == "sType":
            return member.get('values')
    return None


def parse_xml(enum_factory, ext_factory, struct_factory, filename):
    """Parse the XML file. Accumulate results into the factories.

    This parser is a memory efficient iterative XML parser that returns a list
    of VkEnum objects.
    """

    xml = et.parse(filename)

    for enum_type in xml.findall('./enums[@type="enum"]'):
        enum = enum_factory(enum_type.attrib['name'])
        for value in enum_type.findall('./enum'):
            enum.add_value_from_xml(value)

    for value in xml.findall('./feature/require/enum[@extends]'):
        enum = enum_factory.get(value.attrib['extends'])
        if enum is not None:
            enum.add_value_from_xml(value)

    for struct_type in xml.findall('./types/type[@category="struct"]'):
        name = struct_type.attrib['name']
        stype = struct_get_stype(struct_type)
        if stype is not None:
            struct_factory(name, stype=stype)

    platform_define = {}
    for platform in xml.findall('./platforms/platform'):
        name = platform.attrib['name']
        define = platform.attrib['protect']
        platform_define[name] = define

    for ext_elem in xml.findall('./extensions/extension[@supported="vulkan"]'):
        define = None
        if "platform" in ext_elem.attrib:
            define = platform_define[ext_elem.attrib['platform']]
        extension = ext_factory(ext_elem.attrib['name'],
                                number=int(ext_elem.attrib['number']),
                                define=define)

        for value in ext_elem.findall('./require/enum[@extends]'):
            enum = enum_factory.get(value.attrib['extends'])
            if enum is not None:
                enum.add_value_from_xml(value, extension)
        for t in ext_elem.findall('./require/type'):
            struct = struct_factory.get(t.attrib['name'])
            if struct is not None:
                struct.extension = extension

        if define:
            for value in ext_elem.findall('./require/type[@name]'):
                enum = enum_factory.get(value.attrib['name'])
                if enum is not None:
                    enum.set_guard(define)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--xml', required=True,
                        help='Vulkan API XML files',
                        action='append',
                        dest='xml_files')
    parser.add_argument('--outdir',
                        help='Directory to put the generated files in',
                        required=True)

    args = parser.parse_args()

    enum_factory = NamedFactory(VkEnum)
    ext_factory = NamedFactory(VkExtension)
    struct_factory = NamedFactory(VkChainStruct)
    for filename in args.xml_files:
        parse_xml(enum_factory, ext_factory, struct_factory, filename)
    enums = sorted(enum_factory.registry.values(), key=lambda e: e.name)
    extensions = sorted(ext_factory.registry.values(), key=lambda e: e.name)
    structs = sorted(struct_factory.registry.values(), key=lambda e: e.name)

    for template, file_ in [(C_TEMPLATE, os.path.join(args.outdir, 'vk_enum_to_str.c')),
                            (H_TEMPLATE, os.path.join(args.outdir, 'vk_enum_to_str.h'))]:
        with open(file_, 'wb') as f:
            f.write(template.render(
                file=os.path.basename(__file__),
                enums=enums,
                extensions=extensions,
                structs=structs,
                copyright=COPYRIGHT))


if __name__ == '__main__':
    main()
