#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0

import re


_A_VS_AN_RE = re.compile(r' a ([a-z]+:)?([aAeEiIoOxX]\w+\b)(?!:)')

_STARTS_WITH_MACRO_RE = re.compile(r'^[a-z]+:.*')


def _checkAnchorComponents(anchor):
    """Raise an exception if any component of a VUID anchor name is illegal."""
    if anchor:
        # Any other invalid things in an anchor name should be detected here.
        if any((' ' in anchor_part for anchor_part in anchor)):
            raise RuntimeError("Illegal component of a VUID anchor name!")


def _fix_a_vs_an(s):
    """Fix usage (often generated) of the indefinite article 'a' when 'an' is appropriate.

    Explicitly excludes the markup macros."""
    return _A_VS_AN_RE.sub(r' an \1\2', s)


class ValidityCollection:
    """Combines validity for a single entity."""

    def __init__(self, entity_name=None, conventions=None, strict=True):
        self.entity_name = entity_name
        self.conventions = conventions
        self.lines = []
        self.strict = strict

    def possiblyAddExtensionRequirement(self, extension_name, entity_preface):
        """Add an extension-related validity statement if required.

        entity_preface is a string that goes between "must be enabled prior to "
        and the name of the entity, and normally ends in a macro.
        For instance, might be "calling flink:" for a function.
        """
        if extension_name and not extension_name.startswith(self.conventions.api_version_prefix):
            msg = 'The {} extension must: be enabled prior to {}{}'.format(
                self.conventions.formatExtension(extension_name), entity_preface, self.entity_name)
            self.addValidityEntry(msg, anchor=('extension', 'notenabled'))

    def addValidityEntry(self, msg, anchor=None):
        """Add a validity entry, optionally with a VUID anchor.

        If any trailing arguments are supplied,
        an anchor is generated by concatenating them with dashes
        at the end of the VUID anchor name.
        """
        if not msg:
            raise RuntimeError("Tried to add a blank validity line!")
        parts = ['*']
        _checkAnchorComponents(anchor)
        if anchor:
            if not self.entity_name:
                raise RuntimeError('Cannot add a validity entry with an anchor to a collection that does not know its entity name.')
            parts.append('[[{}]]'.format(
                '-'.join(['VUID', self.entity_name] + list(anchor))))
        parts.append(msg)
        combined = _fix_a_vs_an(' '.join(parts))
        if combined in self.lines:
            raise RuntimeError("Duplicate validity added!")
        self.lines.append(combined)

    def addText(self, msg):
        """Add already formatted validity text."""
        if self.strict:
            raise RuntimeError('addText called when collection in strict mode')
        if not msg:
            return
        msg = msg.rstrip()
        if not msg:
            return
        self.lines.append(msg)

    def _extend(self, lines):
        lines = list(lines)
        dupes = set(lines).intersection(self.lines)
        if dupes:
            raise RuntimeError("The two sets contain some shared entries! " + str(dupes))
        self.lines.extend(lines)

    def __iadd__(self, other):
        """Perform += with a string, iterable, or ValidityCollection."""
        if other is None:
            pass
        elif isinstance(other, str):
            if self.strict:
                raise RuntimeError(
                    'Collection += a string when collection in strict mode')
            if not other:
                # empty string
                pass
            elif other.startswith('*'):
                # Handle already-formatted
                self.addText(other)
            else:
                # Do the formatting ourselves.
                self.addValidityEntry(other)
        elif isinstance(other, ValidityEntry):
            if other:
                if other.verbose:
                    print(self.entity_name, 'Appending', str(other))
                self.addValidityEntry(str(other), anchor=other.anchor)
        elif isinstance(other, ValidityCollection):
            if not self.entity_name == other.entity_name:
                raise RuntimeError(
                    "Trying to combine two ValidityCollections for different entities!")
            self._extend(other.lines)
        else:
            # Deal with other iterables.
            self._extend(other)

        return self

    def __bool__(self):
        """Is the collection non-empty?"""
        empty = not self.lines
        return not empty

    @property
    def text(self):
        """Access validity statements as a single string or None."""
        if not self.lines:
            return None
        return '\n'.join(self.lines) + '\n'

    def __str__(self):
        """Access validity statements as a single string or empty string."""
        if not self:
            return ''
        return self.text

    def __repr__(self):
        return '<ValidityCollection: {}>'.format(self.lines)


class ValidityEntry:
    """A single validity line in progress."""

    def __init__(self, text=None, anchor=None):
        """Prepare to add a validity entry, optionally with a VUID anchor.

        An anchor is generated by concatenating the elements of the anchor tuple with dashes
        at the end of the VUID anchor name.
        """
        _checkAnchorComponents(anchor)
        if isinstance(anchor, str):
            # anchor needs to be a tuple
            anchor = (anchor,)

        # VUID does not allow special chars except ":"
        if anchor is not None:
            anchor = [(anchor_value.replace('->', '::').replace('.', '::')) for anchor_value in anchor]

        self.anchor = anchor
        self.parts = []
        self.verbose = False
        if text:
            self.append(text)

    def append(self, part):
        """Append a part of a string.

        If this is the first entry part and the part doesn't start
        with a markup macro, the first character will be capitalized."""
        if not self.parts and not _STARTS_WITH_MACRO_RE.match(part):
            self.parts.append(part[:1].upper())
            self.parts.append(part[1:])
        else:
            self.parts.append(part)
        if self.verbose:
            print('ValidityEntry', id(self), 'after append:', str(self))

    def drop_end(self, n):
        """Remove up to n trailing characters from the string."""
        temp = str(self)
        n = min(len(temp), n)
        self.parts = [temp[:-n]]

    def __iadd__(self, other):
        """Perform += with a string,"""
        self.append(other)
        return self

    def __bool__(self):
        """Return true if we have something more than just an anchor."""
        empty = not self.parts
        return not empty

    def __str__(self):
        """Access validity statement as a single string or empty string."""
        if not self:
            raise RuntimeError("No parts added?")
        return ''.join(self.parts).strip()

    def __repr__(self):
        parts = ['<ValidityEntry: ']
        if self:
            parts.append('"')
            parts.append(str(self))
            parts.append('"')
        else:
            parts.append('EMPTY')
        if self.anchor:
            parts.append(', anchor={}'.format('-'.join(self.anchor)))
        parts.append('>')
        return ''.join(parts)
