#!/usr/bin/env python3
#
# Copyright 2019 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.

"""Provide the utilities for framework generation.
"""

import os
import subprocess
import xml.etree.ElementTree as element_tree

# Extensions unsupported on Android.
_BLOCKED_EXTENSIONS = [
    'VK_EXT_acquire_xlib_display',
    'VK_EXT_direct_mode_display',
    'VK_EXT_directfb_surface',
    'VK_EXT_display_control',
    'VK_EXT_display_surface_counter',
    'VK_EXT_full_screen_exclusive',
    'VK_EXT_headless_surface',
    'VK_EXT_metal_surface',
    'VK_FUCHSIA_imagepipe_surface',
    'VK_GGP_stream_descriptor_surface',
    'VK_KHR_display',
    'VK_KHR_display_swapchain',
    'VK_KHR_external_fence_win32',
    'VK_KHR_external_memory_win32',
    'VK_KHR_external_semaphore_win32',
    'VK_KHR_mir_surface',
    'VK_KHR_wayland_surface',
    'VK_KHR_win32_keyed_mutex',
    'VK_KHR_win32_surface',
    'VK_KHR_xcb_surface',
    'VK_KHR_xlib_surface',
    'VK_MVK_ios_surface',
    'VK_MVK_macos_surface',
    'VK_NN_vi_surface',
    'VK_NV_cooperative_matrix',
    'VK_NV_coverage_reduction_mode',
    'VK_NV_external_memory_win32',
    'VK_NV_win32_keyed_mutex',
    'VK_NVX_image_view_handle',
]

# Extensions having functions exported by the loader.
_EXPORTED_EXTENSIONS = [
    'VK_ANDROID_external_memory_android_hardware_buffer',
    'VK_KHR_android_surface',
    'VK_KHR_surface',
    'VK_KHR_swapchain',
]

# Functions optional on Android even if extension is advertised.
_OPTIONAL_COMMANDS = [
    'vkGetSwapchainGrallocUsageANDROID',
    'vkGetSwapchainGrallocUsage2ANDROID',
]

# Dict for mapping dispatch table to a type.
_DISPATCH_TYPE_DICT = {
    'VkInstance ': 'Instance',
    'VkPhysicalDevice ': 'Instance',
    'VkDevice ': 'Device',
    'VkQueue ': 'Device',
    'VkCommandBuffer ': 'Device'
}

# Dict for mapping a function to its alias.
alias_dict = {}

# List of all the Vulkan functions.
command_list = []

# Dict for mapping a function to an extension.
extension_dict = {}

# Dict for mapping a function to all its parameters.
param_dict = {}

# Dict for mapping a function to its return type.
return_type_dict = {}

# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'.
version_code_list = []

# Dict for mapping a function to the core Vulkan API version.
version_dict = {}


def indent(num):
  """Returns the requested indents.

  Args:
    num: Number of the 4-space indents.
  """
  return '    ' * num


def copyright_and_warning(year):
  """Returns the standard copyright and warning codes.

  Args:
    year: An integer year for the copyright.
  """
  return """\
/*
 * Copyright """ + str(year) + """ 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.
 */

// WARNING: This file is generated. See ../README.md for instructions.

"""


def run_clang_format(args):
  """Run clang format on the file.

  Args:
    args: The file to be formatted.
  """
  clang_call = ['clang-format', '--style', 'file', '-i', args]
  subprocess.check_call(clang_call)


def is_extension_internal(ext):
  """Returns true if an extension is internal to the loader and drivers.

  The loader should not enumerate this extension.

  Args:
    ext: Vulkan extension name.
  """
  return ext == 'VK_ANDROID_native_buffer'


def base_name(cmd):
  """Returns a function name without the 'vk' prefix.

  Args:
    cmd: Vulkan function name.
  """
  return cmd[2:]


def base_ext_name(ext):
  """Returns an extension name without the 'VK_' prefix.

  Args:
    ext: Vulkan extension name.
  """
  return ext[3:]


def version_code(version):
  """Returns the version code from a version string.

  Args:
    version: Vulkan version string.
  """
  return version[11:]


def is_function_supported(cmd):
  """Returns true if a function is core or from a supportable extension.

  Args:
    cmd: Vulkan function name.
  """
  if cmd not in extension_dict:
    return True
  else:
    if extension_dict[cmd] not in _BLOCKED_EXTENSIONS:
      return True
  return False


def get_dispatch_table_type(cmd):
  """Returns the dispatch table type for a function.

  Args:
    cmd: Vulkan function name.
  """
  if cmd not in param_dict:
    return None

  if param_dict[cmd]:
    return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
  return 'Global'


def is_globally_dispatched(cmd):
  """Returns true if the function is global, which is not dispatched.

  Only global functions and functions handled in the loader top without calling
  into lower layers are not dispatched.

  Args:
    cmd: Vulkan function name.
  """
  return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'


def is_instance_dispatched(cmd):
  """Returns true for functions that can have instance-specific dispatch.

  Args:
    cmd: Vulkan function name.
  """
  return (is_function_supported(cmd) and
          get_dispatch_table_type(cmd) == 'Instance')


def is_device_dispatched(cmd):
  """Returns true for functions that can have device-specific dispatch.

  Args:
    cmd: Vulkan function name.
  """
  return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'


def is_extension_exported(ext):
  """Returns true if an extension has functions exported by the loader.

  E.g. applications can directly link to an extension function.

  Args:
    ext: Vulkan extension name.
  """
  return ext in _EXPORTED_EXTENSIONS


def is_function_exported(cmd):
  """Returns true if a function is exported from the Android Vulkan library.

  Functions in the core API and in loader extensions are exported.

  Args:
    cmd: Vulkan function name.
  """
  if is_function_supported(cmd):
    if cmd in extension_dict:
      return is_extension_exported(extension_dict[cmd])
    return True
  return False


def is_instance_dispatch_table_entry(cmd):
  """Returns true if a function is exported and instance-dispatched.

  Args:
    cmd: Vulkan function name.
  """
  if cmd == 'vkEnumerateDeviceLayerProperties':
    # deprecated, unused internally - @dbd33bc
    return False
  return is_function_exported(cmd) and is_instance_dispatched(cmd)


def is_device_dispatch_table_entry(cmd):
  """Returns true if a function is exported and device-dispatched.

  Args:
    cmd: Vulkan function name.
  """
  return is_function_exported(cmd) and is_device_dispatched(cmd)


def init_proc(name, f):
  """Emits code to invoke INIT_PROC or INIT_PROC_EXT.

  Args:
    name: Vulkan function name.
    f: Output file handle.
  """
  f.write(indent(1))
  if name in extension_dict:
    f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
  else:
    f.write('INIT_PROC(')

  if name in _OPTIONAL_COMMANDS:
    f.write('false, ')
  elif version_dict[name] == 'VK_VERSION_1_0':
    f.write('true, ')
  else:
    f.write('false, ')

  if is_instance_dispatched(name):
    f.write('instance, ')
  else:
    f.write('dev, ')

  f.write(base_name(name) + ');\n')


def parse_vulkan_registry():
  """Parses Vulkan registry into the below global variables.

  alias_dict
  command_list
  extension_dict
  param_dict
  return_type_dict
  version_code_list
  version_dict
  """
  registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
                          'external', 'vulkan-headers', 'registry', 'vk.xml')
  tree = element_tree.parse(registry)
  root = tree.getroot()
  for commands in root.iter('commands'):
    for command in commands:
      if command.tag == 'command':
        parameter_list = []
        protoset = False
        cmd_name = ''
        cmd_type = ''
        if command.get('alias') is not None:
          alias = command.get('alias')
          cmd_name = command.get('name')
          alias_dict[cmd_name] = alias
          command_list.append(cmd_name)
          param_dict[cmd_name] = param_dict[alias].copy()
          return_type_dict[cmd_name] = return_type_dict[alias]
        for params in command:
          if params.tag == 'param':
            param_type = ''
            if params.text is not None and params.text.strip():
              param_type = params.text.strip() + ' '
            type_val = params.find('type')
            param_type = param_type + type_val.text
            if type_val.tail is not None:
              param_type += type_val.tail.strip() + ' '
            pname = params.find('name')
            param_name = pname.text
            if pname.tail is not None and pname.tail.strip():
              parameter_list.append(
                  (param_type, param_name, pname.tail.strip()))
            else:
              parameter_list.append((param_type, param_name))
          if params.tag == 'proto':
            for c in params:
              if c.tag == 'type':
                cmd_type = c.text
              if c.tag == 'name':
                cmd_name = c.text
                protoset = True
                command_list.append(cmd_name)
                return_type_dict[cmd_name] = cmd_type
        if protoset:
          param_dict[cmd_name] = parameter_list.copy()

  for exts in root.iter('extensions'):
    for extension in exts:
      apiversion = 'VK_VERSION_1_0'
      if extension.tag == 'extension':
        extname = extension.get('name')
        for req in extension:
          if req.get('feature') is not None:
            apiversion = req.get('feature')
          for commands in req:
            if commands.tag == 'command':
              cmd_name = commands.get('name')
              if cmd_name not in extension_dict:
                extension_dict[cmd_name] = extname
                version_dict[cmd_name] = apiversion

  for feature in root.iter('feature'):
    apiversion = feature.get('name')
    for req in feature:
      for command in req:
        if command.tag == 'command':
          cmd_name = command.get('name')
          if cmd_name in command_list:
            version_dict[cmd_name] = apiversion

  version_code_set = set()
  for version in version_dict.values():
    version_code_set.add(version_code(version))
  for code in sorted(version_code_set):
    version_code_list.append(code)
