#!/usr/bin/python3 -i
#
# Copyright (c) 2013-2019 The Khronos Group Inc.
#
# 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.

# Working-group-specific style conventions,
# used in generation.

import re

from conventions import ConventionsBase


# Modified from default implementation - see category_requires_validation() below
CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask'))


class VulkanConventions(ConventionsBase):
    def formatExtension(self, name):
        """Mark up a name as an extension for the spec."""
        return '`<<{}>>`'.format(name)

    @property
    def null(self):
        """Preferred spelling of NULL."""
        return '`NULL`'

    @property
    def constFlagBits(self):
        """Returns True if static const flag bits should be generated, False if an enumerated type should be generated."""
        return False

    @property
    def structtype_member_name(self):
        """Return name of the structure type member"""
        return 'sType'

    @property
    def nextpointer_member_name(self):
        """Return name of the structure pointer chain member"""
        return 'pNext'

    @property
    def valid_pointer_prefix(self):
        """Return prefix to pointers which must themselves be valid"""
        return 'valid'

    def is_structure_type_member(self, paramtype, paramname):
        """Determine if member type and name match the structure type member."""
        return paramtype == 'VkStructureType' and paramname == self.structtype_member_name

    def is_nextpointer_member(self, paramtype, paramname):
        """Determine if member type and name match the next pointer chain member."""
        return paramtype == 'void' and paramname == self.nextpointer_member_name

    def generate_structure_type_from_name(self, structname):
        """Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO"""
        structure_type_parts = []
        # Tokenize into "words"
        for elem in re.findall(r'(([A-Z][a-z]+)|([A-Z][A-Z]+))', structname):
            if elem[0] == 'Vk':
                structure_type_parts.append('VK_STRUCTURE_TYPE')
            else:
                structure_type_parts.append(elem[0].upper())
        return '_'.join(structure_type_parts)

    @property
    def warning_comment(self):
        """Return warning comment to be placed in header of generated Asciidoctor files"""
        return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry'

    @property
    def file_suffix(self):
        """Return suffix of generated Asciidoctor files"""
        return '.txt'

    def api_name(self, spectype='api'):
        """Return API or specification name for citations in ref pages.ref
           pages should link to for

           spectype is the spec this refpage is for: 'api' is the Vulkan API
           Specification. Defaults to 'api'. If an unrecognized spectype is
           given, returns None.
        """
        if spectype == 'api' or spectype is None:
            return 'Vulkan'
        else:
            return None

    @property
    def xml_supported_name_of_api(self):
        """Return the supported= attribute used in API XML"""
        return 'vulkan'

    @property
    def api_prefix(self):
        """Return API token prefix"""
        return 'VK_'

    @property
    def write_contacts(self):
        """Return whether contact list should be written to extension appendices"""
        return True

    @property
    def write_refpage_include(self):
        """Return whether refpage include should be written to extension appendices"""
        return True

    @property
    def member_used_for_unique_vuid(self):
        """Return the member name used in the VUID-...-...-unique ID."""
        return self.structtype_member_name

    def is_externsync_command(self, protoname):
        """Returns True if the protoname element is an API command requiring
           external synchronization
        """
        return protoname is not None and 'vkCmd' in protoname

    def is_api_name(self, name):
        """Returns True if name is in the reserved API namespace.
        For Vulkan, these are names with a case-insensitive 'vk' prefix, or
        a 'PFN_vk' function pointer type prefix.
        """
        return name[0:2].lower() == 'vk' or name[0:6] == 'PFN_vk'

    def specURL(self, spectype='api'):
        """Return public registry URL which ref pages should link to for the
           current all-extensions HTML specification, so xrefs in the
           asciidoc source that aren't to ref pages can link into it
           instead. N.b. this may need to change on a per-refpage basis if
           there are multiple documents involved.
        """
        return 'https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html'

    @property
    def xml_api_name(self):
        """Return the name used in the default API XML registry for the default API"""
        return 'vulkan'

    @property
    def registry_path(self):
        """Return relpath to the default API XML registry in this project."""
        return 'xml/vk.xml'

    @property
    def specification_path(self):
        """Return relpath to the Asciidoctor specification sources in this project."""
        return '../appendices/meta'

    @property
    def extra_refpage_headers(self):
        """Return any extra text to add to refpage headers."""
        return 'include::../config/attribs.txt[]'

    @property
    def extension_index_prefixes(self):
        """Return a list of extension prefixes used to group extension refpages."""
        return ['VK_KHR', 'VK_EXT', 'VK']

    @property
    def unified_flag_refpages(self):
        """Returns True if Flags/FlagBits refpages are unified, False if
           they're separate.
        """
        return False

    @property
    def spec_reflow_path(self):
        """Return the relative path to the spec source folder to reflow"""
        return '.'

    @property
    def spec_no_reflow_dirs(self):
        """Return a set of directories not to automatically descend into
           when reflowing spec text
        """
        return ('scripts', 'style')

    @property
    def zero(self):
        return '`0`'

    def category_requires_validation(self, category):
        """Return True if the given type 'category' always requires validation.

        Overridden because Vulkan doesn't require "valid" text for basetype in the spec right now."""
        return category in CATEGORIES_REQUIRING_VALIDATION
