#!/usr/bin/env python3
#
# Copyright (C) 2012 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.

"""Generates default implementations of operator<< for enum types."""

import codecs
import re
import sys


_ENUM_START_RE = re.compile(
    r'\benum\b\s+(class\s+)?(?:HIDDEN |EXPORT )?(\S+)\s+:?.*\{(\s+// private)?')
_ENUM_VALUE_RE = re.compile(r'([A-Za-z0-9_]+)(.*)')
_ENUM_END_RE = re.compile(r'^\s*\};$')
_ENUMS = {}
_NAMESPACES = {}
_ENUM_CLASSES = {}


def Confused(filename, line_number, line):
    sys.stderr.write('%s:%d: confused by:\n%s\n' %
                     (filename, line_number, line))
    raise Exception("giving up!")
    sys.exit(1)


def ProcessFile(filename):
    lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')

    class EnumLines:
        def __init__(self, ns, ec):
            self.namespaces = ns
            self.enclosing_classes = ec
            self.lines = []

    def generate_enum_lines(l):
        line_number = 0
        enum_lines = None
        namespaces = []
        enclosing_classes = []

        for raw_line in l:
            line_number += 1

            if enum_lines is None:
                # Is this the start of a new enum?
                m = _ENUM_START_RE.search(raw_line)
                if m:
                    # Yes, so create new line list.
                    enum_lines = EnumLines(namespaces[:], enclosing_classes[:])
                    enum_lines.lines.append((raw_line, line_number))
                    continue

                # Is this the start or end of a namespace?
                m = re.search(r'^namespace (\S+) (HIDDEN |EXPORT )?\{', raw_line)
                if m:
                    namespaces.append(m.group(1))
                    continue
                m = re.search(r'^\}\s+// namespace', raw_line)
                if m:
                    namespaces = namespaces[0:len(namespaces) - 1]
                    continue

                # Is this the start or end of an enclosing class or struct?
                m = re.search(
                    r'^\s*(?:class|struct)(?: HIDDEN| EXPORT)?(?: MANAGED)?(?: PACKED\([0-9]\))? (\S+).* \{', raw_line)
                if m:
                    enclosing_classes.append(m.group(1))
                    continue

                # End of class/struct -- be careful not to match "do { ... } while" constructs by accident
                m = re.search(r'^\s*\}(\s+)?(while)?(.+)?;', raw_line)
                if m and not m.group(2):
                    enclosing_classes = enclosing_classes[0:len(enclosing_classes) - 1]
                    continue

                continue

            # Is this the end of the current enum?
            m = _ENUM_END_RE.search(raw_line)
            if m:
                if enum_lines is None:
                    Confused(filename, line_number, raw_line)
                yield enum_lines
                enum_lines = None
                continue

            # Append the line
            enum_lines.lines.append((raw_line, line_number))

    for enum_lines in generate_enum_lines(lines):
        m = _ENUM_START_RE.search(enum_lines.lines[0][0])
        if m.group(3) is not None:
            # Skip private enums.
            continue

        # Add an empty entry to _ENUMS for this enum.
        is_enum_class = m.group(1) is not None
        enum_name = m.group(2)
        if len(enum_lines.enclosing_classes) > 0:
            enum_name = '::'.join(enum_lines.enclosing_classes) + '::' + enum_name
        _ENUMS[enum_name] = []
        _NAMESPACES[enum_name] = '::'.join(enum_lines.namespaces)
        _ENUM_CLASSES[enum_name] = is_enum_class

        def generate_non_empty_line(lines):
            for raw_line, line_number in lines:
                # Strip // comments.
                line = re.sub(r'//.*', '', raw_line)
                # Strip whitespace.
                line = line.strip()
                # Skip blank lines.
                if len(line) == 0:
                    continue

                # The only useful thing in comments is the <<alternate text>> syntax for
                # overriding the default enum value names. Pull that out...
                enum_text = None
                m_comment = re.search(r'// <<(.*?)>>', raw_line)
                if m_comment:
                    enum_text = m_comment.group(1)

                yield (line, enum_text, raw_line, line_number)

        for line, enum_text, raw_line, line_number in generate_non_empty_line(enum_lines.lines[1:]):
            # Since we know we're in an enum type, and we're not looking at a comment
            # or a blank line, this line should be the next enum value...
            m = _ENUM_VALUE_RE.search(line)
            if not m:
                Confused(filename, line_number, raw_line)
            enum_value = m.group(1)

            # By default, we turn "kSomeValue" into "SomeValue".
            if enum_text is None:
                enum_text = enum_value
                if enum_text.startswith('k'):
                    enum_text = enum_text[1:]

            # Check that we understand the line (and hopefully do not parse incorrectly), or should
            # filter.
            rest = m.group(2).strip()

            # With "kSomeValue = kOtherValue," we take the original and skip later synonyms.
            # TODO: check that the rhs is actually an existing value.
            if rest.startswith('= k'):
                continue

            # Remove trailing comma.
            if rest.endswith(','):
                rest = rest[:-1]

            # We now expect rest to be empty, or an assignment to an "expression."
            if len(rest):
                # We want to lose the expression "= [exp]". As we do not have a real C parser, just
                # assume anything without a comma is valid.
                m_exp = re.match('= [^,]+$', rest)
                if m_exp is None:
                    sys.stderr.write('%s\n' % (rest))
                    Confused(filename, line_number, raw_line)

            # If the enum is scoped, we must prefix enum value with enum name (which is already prefixed
            # by enclosing classes).
            if is_enum_class:
                enum_value = enum_name + '::' + enum_value
            else:
                if len(enum_lines.enclosing_classes) > 0:
                    enum_value = '::'.join(enum_lines.enclosing_classes) + '::' + enum_value

            _ENUMS[enum_name].append((enum_value, enum_text))


def main():
    local_path = sys.argv[1]
    header_files = []
    for header_file in sys.argv[2:]:
        header_files.append(header_file)
        ProcessFile(header_file)

    print('#include <iostream>')
    print('')

    for header_file in header_files:
        header_file = header_file.replace(local_path + '/', '')
        print('#include "%s"' % header_file)

    print('')

    for enum_name in _ENUMS:
        print('// This was automatically generated by art/tools/generate_operator_out.py --- do not edit!')

        namespaces = _NAMESPACES[enum_name].split('::')
        for namespace in namespaces:
            print('namespace %s {' % namespace)

        print(
            'std::ostream& operator<<(std::ostream& os, %s rhs) {' % enum_name)
        print('  switch (rhs) {')
        for (enum_value, enum_text) in _ENUMS[enum_name]:
            print('    case %s: os << "%s"; break;' % (enum_value, enum_text))
        if not _ENUM_CLASSES[enum_name]:
            print(
                '    default: os << "%s[" << static_cast<int>(rhs) << "]"; break;' % enum_name)
        print('  }')
        print('  return os;')
        print('}')

        for namespace in reversed(namespaces):
            print('}  // namespace %s' % namespace)
        print('')

    sys.exit(0)


if __name__ == '__main__':
    main()
