#!/usr/bin/env python3
# Copyright 2019 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os, json, sys
from collections import namedtuple
import xml.etree.ElementTree as etree

from generator_lib import Generator, run_generator, FileRender


class ProcName:
    def __init__(self, gl_name, proc_name=None):
        assert gl_name.startswith('gl')
        if proc_name == None:
            proc_name = gl_name[2:]

        self.gl_name = gl_name
        self.proc_name = proc_name

    def glProcName(self):
        return self.gl_name

    def ProcName(self):
        return self.proc_name

    def PFNPROCNAME(self):
        return 'PFN' + self.gl_name.upper() + 'PROC'

    def __repr__(self):
        return 'Proc("{}", "{}")'.format(self.gl_name, self.proc_name)


ProcParam = namedtuple('ProcParam', ['name', 'type'])


class Proc:
    def __init__(self, element):
        # Type declaration for return values and arguments all have the same
        # (weird) format.
        # <element>[A][<ptype>B</ptype>][C]<other stuff.../></element>
        #
        # Some examples are:
        #   <proto>void <name>glFinish</name></proto>
        #   <proto><ptype>GLenum</ptype><name>glFenceSync</name></proto>
        #   <proto>const <ptype>GLubyte</ptype> *<name>glGetString</name></proto>
        #
        # This handles all the shapes found in gl.xml except for this one that
        # has an array specifier after </name>:
        #   <param><ptype>GLuint</ptype> <name>baseAndCount</name>[2]</param>
        def parse_type_declaration(element):
            result = ''
            if element.text != None:
                result += element.text
            ptype = element.find('ptype')
            if ptype != None:
                result += ptype.text
                if ptype.tail != None:
                    result += ptype.tail
            return result.strip()

        proto = element.find('proto')

        self.return_type = parse_type_declaration(proto)

        self.params = []
        for param in element.findall('./param'):
            self.params.append(
                ProcParam(
                    param.find('name').text, parse_type_declaration(param)))

        self.gl_name = proto.find('name').text
        self.alias = None
        if element.find('alias') != None:
            self.alias = element.find('alias').attrib['name']

    def glProcName(self):
        return self.gl_name

    def ProcName(self):
        assert self.gl_name.startswith('gl')
        return self.gl_name[2:]

    def PFNGLPROCNAME(self):
        return 'PFN' + self.gl_name.upper() + 'PROC'

    def __repr__(self):
        return 'Proc("{}")'.format(self.gl_name)


EnumDefine = namedtuple('EnumDefine', ['name', 'value'])
Version = namedtuple('Version', ['major', 'minor'])
VersionBlock = namedtuple('VersionBlock', ['version', 'procs', 'enums'])
HeaderBlock = namedtuple('HeaderBlock', ['description', 'procs', 'enums'])
ExtensionBlock = namedtuple('ExtensionBlock',
                            ['extension', 'procs', 'enums', 'supported_specs'])


def parse_version(version):
    return Version(*map(int, version.split('.')))


def compute_params(root, supported_extensions):
    # Parse all the commands and enums
    all_procs = {}
    for command in root.findall('''commands[@namespace='GL']/command'''):
        proc = Proc(command)
        assert proc.gl_name not in all_procs
        all_procs[proc.gl_name] = proc

    all_enums = {}
    for enum in root.findall('''enums[@namespace='GL']/enum'''):
        enum_name = enum.attrib['name']
        # Special case an enum we'll never use that has different values in GL and GLES
        if enum_name == 'GL_ACTIVE_PROGRAM_EXT':
            continue

        assert enum_name not in all_enums
        all_enums[enum_name] = EnumDefine(enum_name, enum.attrib['value'])

    # Get the list of all Desktop OpenGL function removed by the Core Profile.
    core_removed_procs = set()
    for proc in root.findall('''feature/remove[@profile='core']/command'''):
        core_removed_procs.add(proc.attrib['name'])

    # Get list of enums and procs per OpenGL ES/Desktop OpenGL version
    def parse_version_blocks(api, removed_procs=set()):
        blocks = []
        for section in root.findall('''feature[@api='{}']'''.format(api)):
            section_procs = []
            for command in section.findall('./require/command'):
                proc_name = command.attrib['name']
                assert all_procs[proc_name].alias == None
                if proc_name not in removed_procs:
                    section_procs.append(all_procs[proc_name])

            section_enums = []
            for enum in section.findall('./require/enum'):
                section_enums.append(all_enums[enum.attrib['name']])

            blocks.append(
                VersionBlock(parse_version(section.attrib['number']),
                             section_procs, section_enums))

        return blocks

    gles_blocks = parse_version_blocks('gles2')
    desktop_gl_blocks = parse_version_blocks('gl', core_removed_procs)

    def parse_extension_block(extension):
        section = root.find(
            '''extensions/extension[@name='{}']'''.format(extension))
        supported_specs = section.attrib['supported'].split('|')
        section_procs = []
        for command in section.findall('./require/command'):
            proc_name = command.attrib['name']
            assert all_procs[proc_name].alias == None
            section_procs.append(all_procs[proc_name])

        section_enums = []
        for enum in section.findall('./require/enum'):
            section_enums.append(all_enums[enum.attrib['name']])

        return ExtensionBlock(extension, section_procs, section_enums,
                              supported_specs)

    extension_desktop_gl_blocks = []
    extension_gles_blocks = []
    for extension in supported_extensions:
        extension_block = parse_extension_block(extension)
        if 'gl' in extension_block.supported_specs:
            extension_desktop_gl_blocks.append(extension_block)
        if 'gles2' in extension_block.supported_specs:
            extension_gles_blocks.append(extension_block)

    # Compute the blocks for headers such that there is no duplicate definition
    already_added_header_procs = set()
    already_added_header_enums = set()
    header_blocks = []

    def add_header_block(description, block):
        block_procs = []
        for proc in block.procs:
            if not proc.glProcName() in already_added_header_procs:
                already_added_header_procs.add(proc.glProcName())
                block_procs.append(proc)

        block_enums = []
        for enum in block.enums:
            if not enum.name in already_added_header_enums:
                already_added_header_enums.add(enum.name)
                block_enums.append(enum)

        if len(block_procs) > 0 or len(block_enums) > 0:
            header_blocks.append(
                HeaderBlock(description, block_procs, block_enums))

    for block in gles_blocks:
        add_header_block(
            'OpenGL ES {}.{}'.format(block.version.major, block.version.minor),
            block)

    for block in desktop_gl_blocks:
        add_header_block(
            'Desktop OpenGL {}.{}'.format(block.version.major,
                                          block.version.minor), block)

    for block in extension_desktop_gl_blocks:
        add_header_block(block.extension, block)

    for block in extension_gles_blocks:
        add_header_block(block.extension, block)

    return {
        'gles_blocks': gles_blocks,
        'desktop_gl_blocks': desktop_gl_blocks,
        'extension_desktop_gl_blocks': extension_desktop_gl_blocks,
        'extension_gles_blocks': extension_gles_blocks,
        'header_blocks': header_blocks,
    }


class OpenGLLoaderGenerator(Generator):
    def get_description(self):
        return 'Generates code to load OpenGL function pointers'

    def add_commandline_arguments(self, parser):
        parser.add_argument('--gl-xml',
                            required=True,
                            type=str,
                            help='The Khronos gl.xml to use.')
        parser.add_argument(
            '--supported-extensions',
            required=True,
            type=str,
            help=
            'The JSON file that defines the OpenGL and GLES extensions to use.'
        )

    def get_file_renders(self, args):
        supported_extensions = []
        with open(args.supported_extensions) as f:
            supported_extensions_json = json.loads(f.read())
            supported_extensions = supported_extensions_json[
                'supported_extensions']

        params = compute_params(
            etree.parse(args.gl_xml).getroot(), supported_extensions)

        return [
            FileRender(
                'opengl/OpenGLFunctionsBase.cpp',
                'src/dawn/native/opengl/OpenGLFunctionsBase_autogen.cpp',
                [params]),
            FileRender('opengl/OpenGLFunctionsBase.h',
                       'src/dawn/native/opengl/OpenGLFunctionsBase_autogen.h',
                       [params]),
            FileRender('opengl/opengl_platform.h',
                       'src/dawn/native/opengl/opengl_platform_autogen.h',
                       [params]),
        ]

    def get_dependencies(self, args):
        return [
            os.path.abspath(args.gl_xml),
            os.path.abspath(args.supported_extensions)
        ]


if __name__ == '__main__':
    sys.exit(run_generator(OpenGLLoaderGenerator()))
