#!/usr/bin/env python
#
# Copyright 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
from operator import itemgetter
import collections
import os.path
import re
import sys


# Avoid endlessly adding to the path if this module is imported multiple
# times, e.g. in an interactive session
regpath = os.path.join(sys.path[0], "registry")
if sys.path[1] != regpath:
    sys.path.insert(1, regpath)
import reg


AEP_EXTENSIONS = [
    'GL_KHR_blend_equation_advanced',
    'GL_KHR_debug',
    'GL_KHR_texture_compression_astc_ldr',
    'GL_OES_sample_shading',
    'GL_OES_sample_variables',
    'GL_OES_shader_image_atomic',
    'GL_OES_shader_multisample_interpolation',
    'GL_OES_texture_stencil8',
    'GL_OES_texture_storage_multisample_2d_array',
    'GL_EXT_copy_image',
    'GL_EXT_draw_buffers_indexed',
    'GL_EXT_geometry_shader',
    'GL_EXT_gpu_shader5',
    'GL_EXT_primitive_bounding_box',
    'GL_EXT_shader_io_blocks',
    'GL_EXT_tessellation_shader',
    'GL_EXT_texture_border_clamp',
    'GL_EXT_texture_buffer',
    'GL_EXT_texture_cube_map_array',
    'GL_EXT_texture_sRGB_decode']


def nonestr(s):
    return s if s else ""

def parseProto(elem):
    type = nonestr(elem.text)
    name = None
    for subelem in elem:
        text = nonestr(subelem.text)
        if subelem.tag == 'name':
            name = text
        else:
            type += text
            type += nonestr(subelem.tail)
    return (type.strip(), name)

def parseParam(elem):
    name = elem.find('name').text
    declaration = ''.join(elem.itertext())
    return (name, declaration)

# Format a list of (type, declaration) tuples as a C-style parameter list
def fmtParams(params):
    if not params:
        return 'void'
    return ', '.join(p[1] for p in params)

# Format a list of (type, declaration) tuples as a C-style argument list
def fmtArgs(params):
    return ', '.join(p[0] for p in params)

def overrideSymbolName(sym, apiname):
    # The wrapper intercepts various glGet and glGetString functions and
    # (sometimes) calls the generated thunk which dispatches to the
    # driver's implementation
    wrapped_get_syms = {
        'gles1' : [
            'glGetString'
        ],
        'gles2' : [
            'glGetString',
            'glGetStringi',
            'glGetBooleanv',
            'glGetFloatv',
            'glGetIntegerv',
            'glGetInteger64v',
        ],
    }
    if sym in wrapped_get_syms.get(apiname):
        return '__' + sym
    else:
        return sym


# Generate API trampoline templates:
#   <rtype> API_ENTRY(<name>)(<params>) {
#       CALL_GL_API(<name>, <args>);
#       // or
#       CALL_GL_API_RETURN(<name>, <args>);
#   }
class TrampolineGen(reg.OutputGenerator):
    def __init__(self):
        reg.OutputGenerator.__init__(self, sys.stderr, sys.stderr, None)

    def genCmd(self, cmd, name):
        reg.OutputGenerator.genCmd(self, cmd, name)

        rtype, fname = parseProto(cmd.elem.find('proto'))
        params = [parseParam(p) for p in cmd.elem.findall('param')]
        call = 'CALL_GL_API' if rtype == 'void' else 'CALL_GL_API_RETURN'
        print('%s API_ENTRY(%s)(%s) {\n'
              '    %s(%s%s%s);\n'
              '}'
              % (rtype, overrideSymbolName(fname, self.genOpts.apiname),
                 fmtParams(params), call, fname,
                 ', ' if len(params) > 0 else '',
                 fmtArgs(params)),
              file=self.outFile)



# Collect all API prototypes across all families, remove duplicates,
# emit to entries.in and enums.in files.
class ApiGenerator(reg.OutputGenerator):
    def __init__(self):
        reg.OutputGenerator.__init__(self, sys.stderr, sys.stderr, None)
        self.cmds = []
        self.enums = collections.OrderedDict()

    def genCmd(self, cmd, name):
        reg.OutputGenerator.genCmd(self, cmd, name)
        rtype, fname = parseProto(cmd.elem.find('proto'))
        params = [parseParam(p) for p in cmd.elem.findall('param')]
        self.cmds.append({'rtype': rtype, 'name': fname, 'params': params})

    def genEnum(self, enuminfo, name):
        reg.OutputGenerator.genEnum(self, enuminfo, name)
        value = enuminfo.elem.get('value')

        # Skip bitmask enums. Pattern matches:
        # - GL_DEPTH_BUFFER_BIT
        # - GL_MAP_INVALIDATE_BUFFER_BIT_EXT
        # - GL_COLOR_BUFFER_BIT1_QCOM
        # but not
        # - GL_DEPTH_BITS
        # - GL_QUERY_COUNTER_BITS_EXT
        #
        # TODO: Assuming a naming pattern and using a regex is what the
        # old glenumsgen script did. But the registry XML knows which enums are
        # parts of bitmask groups, so we should just use that. I'm not sure how
        # to get the information out though, and it's not critical right now,
        # so leaving for later.
        if re.search('_BIT($|\d*_)', name):
            return

        # Skip non-hex values (GL_TRUE, GL_FALSE, header guard junk)
        if not re.search('0x[0-9A-Fa-f]+', value):
            return

        # Append 'u' or 'ull' type suffix if present
        type = enuminfo.elem.get('type')
        if type and type != 'i':
            value += type

        if value not in self.enums:
            self.enums[value] = name

    def finish(self):
        # sort by function name, remove duplicates
        self.cmds.sort(key=itemgetter('name'))
        cmds = []
        for cmd in self.cmds:
            if len(cmds) == 0 or cmd != cmds[-1]:
                cmds.append(cmd)
        self.cmds = cmds

    # Write entries.in
    def writeEntries(self, outfile):
        for cmd in self.cmds:
            print('GL_ENTRY(%s, %s, %s)'
                  % (cmd['rtype'], cmd['name'], fmtParams(cmd['params'])),
                  file=outfile)

    # Write enums.in
    def writeEnums(self, outfile):
        for enum in self.enums.iteritems():
            print('GL_ENUM(%s,%s)' % (enum[0], enum[1]), file=outfile)


# Generate .spec entries for use by legacy 'gen' script
class SpecGenerator(reg.OutputGenerator):
    def __init__(self):
        reg.OutputGenerator.__init__(self, sys.stderr, sys.stderr, None)

    def genCmd(self, cmd, name):
        reg.OutputGenerator.genCmd(self, cmd, name)
        rtype, fname = parseProto(cmd.elem.find('proto'))
        params = [parseParam(p) for p in cmd.elem.findall('param')]

        print('%s %s ( %s )' % (rtype, fname, fmtParams(params)),
              file=self.outFile)


if __name__ == '__main__':
    registry = reg.Registry()
    registry.loadFile('registry/gl.xml')

    registry.setGenerator(TrampolineGen())
    TRAMPOLINE_OPTIONS = [
        reg.GeneratorOptions(
            apiname             = 'gles1',
            profile             = 'common',
            filename            = '../../libs/GLES_CM/gl_api.in'),
        reg.GeneratorOptions(
            apiname             = 'gles1',
            profile             = 'common',
            emitversions        = None,
            defaultExtensions   = 'gles1',
            filename            = '../../libs/GLES_CM/glext_api.in'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            filename            = '../../libs/GLES2/gl2_api.in'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            emitversions        = None,
            defaultExtensions   = 'gles2',
            filename            = '../../libs/GLES2/gl2ext_api.in')]
    for opts in TRAMPOLINE_OPTIONS:
        registry.apiGen(opts)

    apigen = ApiGenerator()
    registry.setGenerator(apigen)
    API_OPTIONS = [
        # Generate non-extension versions of each API first, then extensions,
        # so that if an extension enum was later standardized, we see the non-
        # suffixed version first.
        reg.GeneratorOptions(
            apiname             = 'gles1',
            profile             = 'common'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common'),
        reg.GeneratorOptions(
            apiname             = 'gles1',
            profile             = 'common',
            emitversions        = None,
            defaultExtensions   = 'gles1'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            emitversions        = None,
            defaultExtensions   = 'gles2')]
    for opts in API_OPTIONS:
        registry.apiGen(opts)
    apigen.finish()
    with open('../../libs/entries.in', 'w') as f:
        apigen.writeEntries(f)
    with open('../../libs/enums.in', 'w') as f:
        apigen.writeEnums(f)

    registry.setGenerator(SpecGenerator())
    SPEC_OPTIONS = [
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            versions            = '3\.1',
            filename            = '../glgen/specs/gles11/GLES31.spec'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            emitversions        = None,
            defaultExtensions   = None,
            addExtensions       = '^({})$'.format('|'.join(AEP_EXTENSIONS)),
            filename            = '../glgen/specs/gles11/GLES31Ext.spec'),
        reg.GeneratorOptions(
            apiname             = 'gles2',
            profile             = 'common',
            versions            = '3\.2',
            filename            = '../glgen/specs/gles11/GLES32.spec')]
    # SpecGenerator creates a good starting point, but the CFunc.java parser is
    # so terrible that the .spec file needs a lot of manual massaging before
    # it works. Commenting this out to avoid accidentally overwriting all the
    # manual modifications.
    #
    # Eventually this script should generate the Java and JNI code directly,
    # skipping the intermediate .spec step, and obsoleting the existing
    # ../glgen system.
    #
    # for opts in SPEC_OPTIONS:
    #     registry.apiGen(opts)

