# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# pylint: disable=import-error,print-statement,relative-import

import copy
import re

SPECIAL_TOKENS = [
    # This list should be sorted by length.
    'WebCodecs',
    'WebSocket',
    'String16',
    'Float32',
    'Float64',
    'Base64',
    'IFrame',
    'Latin1',
    'MathML',
    'PlugIn',
    'SQLite',
    'Uint16',
    'Uint32',
    'WebGL2',
    'webgl2',
    'WebGPU',
    'ASCII',
    'CSSOM',
    'CType',
    'DList',
    'Int16',
    'Int32',
    'MPath',
    'OList',
    'TSpan',
    'UList',
    'UTF16',
    'Uint8',
    'WebGL',
    'XPath',
    'ETC1',
    'etc1',
    'HTML',
    'Int8',
    'S3TC',
    's3tc',
    'SPv2',
    'UTF8',
    'sRGB',
    'URLs',
    'API',
    'CSS',
    'DNS',
    'DOM',
    'EXT',
    'RTC',
    'SVG',
    'XSS',
    '2D',
    'AX',
    'FE',
    'JS',
    'V0',
    'V8',
    'v8',
    'XR',
]

_SPECIAL_TOKENS_WITH_NUMBERS = [
    token for token in SPECIAL_TOKENS if re.search(r'[0-9]', token)
]

# Applying _TOKEN_PATTERNS repeatedly should capture any sequence of a-z, A-Z,
# 0-9.
_TOKEN_PATTERNS = [
    # 'Foo' 'foo'
    '[A-Z]?[a-z]+',
    # The following pattern captures only 'FOO' in 'FOOElement'.
    '[A-Z]+(?![a-z])',
    # '2D' '3D', but not '2Dimension'
    '[0-9][Dd](?![a-z])',
    '[0-9]+',
]

_TOKEN_RE = re.compile(r'(' + '|'.join(SPECIAL_TOKENS + _TOKEN_PATTERNS) +
                       r')')


def tokenize_name(name):
    """Tokenize the specified name.

    A token consists of A-Z, a-z, and 0-9 characters. Other characters work as
    token delimiters, and the resultant list won't contain such characters.
    Capital letters also work as delimiters.  E.g. 'FooBar-baz' is tokenized to
    ['Foo', 'Bar', 'baz']. See _TOKEN_PATTERNS for more details.

    This function detects special cases that are not easily discernible without
    additional knowledge, such as recognizing that in SVGSVGElement, the first
    two SVGs are separate tokens, but WebGL is one token.

    Returns:
        A list of token strings.

    """

    # In case |name| is written in lowerCamelCase, we try to match special
    # tokens that contains numbers ignoring cases only at the first step.
    tokens = []
    match = re.search(r'^(' + '|'.join(_SPECIAL_TOKENS_WITH_NUMBERS) + r')',
                      name, re.IGNORECASE)
    if match:
        tokens.append(match.group(0))
        name = name[match.end(0):]

    return tokens + _TOKEN_RE.findall(name)


class NameStyleConverter(object):
    """Converts names from camelCase to various other styles.
    """

    def __init__(self, name):
        self.tokens = tokenize_name(name)
        self._original = name

    @property
    def original(self):
        return self._original

    def __str__(self):
        return self._original

    # Make this class workable with sort().
    def __lt__(self, other):
        return self.original < other.original

    # Make this class workable with groupby().
    def __eq__(self, other):
        return self.original == other.original

    # If __eq__() is defined then a custom __hash__() needs to be defined.
    def __hash__(self):
        return hash(self.original)

    def to_snake_case(self):
        """Snake case is the file and variable name style per Google C++ Style
           Guide:
           https://google.github.io/styleguide/cppguide.html#Variable_Names

           Also known as the hacker case.
           https://en.wikipedia.org/wiki/Snake_case
        """
        return '_'.join([token.lower() for token in self.tokens])

    def to_upper_camel_case(self):
        """Upper-camel case is the class and function name style per
           Google C++ Style Guide:
           https://google.github.io/styleguide/cppguide.html#Function_Names

           Also known as the PascalCase.
           https://en.wikipedia.org/wiki/Camel_case.
        """
        tokens = self.tokens
        # If the first token is one of SPECIAL_TOKENS, we should replace the
        # token with the matched special token.
        # e.g. ['css', 'External', 'Scanner', 'Preload'] => 'CSSExternalScannerPreload'
        if tokens and tokens[0].lower() == tokens[0]:
            for special in SPECIAL_TOKENS:
                if special.lower() == tokens[0]:
                    tokens = copy.deepcopy(tokens)
                    tokens[0] = special
                    break
        return ''.join([token[0].upper() + token[1:] for token in tokens])

    def to_lower_camel_case(self):
        """Lower camel case is the name style for attribute names and operation
           names in web platform APIs.
           e.g. 'addEventListener', 'documentURI', 'fftSize'
           https://en.wikipedia.org/wiki/Camel_case.
        """
        if not self.tokens:
            return ''
        return self.tokens[0].lower() + ''.join(
            [token[0].upper() + token[1:] for token in self.tokens[1:]])

    def to_macro_case(self):
        """Macro case is the macro name style per Google C++ Style Guide:
           https://google.github.io/styleguide/cppguide.html#Macro_Names
        """
        return '_'.join([token.upper() for token in self.tokens])

    def to_all_cases(self):
        return {
            'snake_case': self.to_snake_case(),
            'upper_camel_case': self.to_upper_camel_case(),
            'macro_case': self.to_macro_case(),
        }

    # Use the following high level naming functions which describe the semantics
    # of the name, rather than a particular style.

    def to_class_name(self, prefix=None, suffix=None):
        """Represents this name as a class name in Chromium C++ style.

        i.e. UpperCamelCase.
        """
        camel_prefix = prefix[0].upper() + prefix[1:].lower() if prefix else ''
        camel_suffix = suffix[0].upper() + suffix[1:].lower() if suffix else ''
        return camel_prefix + self.to_upper_camel_case() + camel_suffix

    def to_class_data_member(self, prefix=None, suffix=None):
        """Represents this name as a data member name in Chromium C++ style.

        i.e. snake_case_with_trailing_underscore_.
        """
        lower_prefix = prefix.lower() + '_' if prefix else ''
        lower_suffix = suffix.lower() + '_' if suffix else ''
        return lower_prefix + self.to_snake_case() + '_' + lower_suffix

    def to_function_name(self, prefix=None, suffix=None):
        """Represents this name as a function name in Blink C++ style.

        i.e. UpperCamelCase
        Note that this function should not be used for IDL operation names and
        C++ functions implementing IDL operations and attributes.
        """
        camel_prefix = prefix[0].upper() + prefix[1:].lower() if prefix else ''
        camel_suffix = ''
        if type(suffix) is list:
            for item in suffix:
                camel_suffix += item[0].upper() + item[1:].lower()
        elif suffix:
            camel_suffix = suffix[0].upper() + suffix[1:].lower()
        return camel_prefix + self.to_upper_camel_case() + camel_suffix

    def to_enum_value(self):
        """Represents this name as an enum value in Blink C++ style.

        i.e. kUpperCamelCase
        """
        return 'k' + self.to_upper_camel_case()

    def to_header_guard(self):
        """Represents this name as a header guard style in Chromium C++ style.

        i.e. THIRD_PARTY_BLINK_RENDERER_MODULES_MODULES_EXPORT_H_
        """
        return re.sub(r'[-/.]', '_', self.to_macro_case()) + '_'
