#!/usr/bin/python
#
# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Generate event interfaces .json5 file (EventInterfaces.json5).

The event interfaces .json5 file contains a list of all Event interfaces, i.e.,
all interfaces that inherit from Event, including Event itself,
together with certain extended attributes.

Paths are in POSIX format, and relative to Source/.

This list is used in core/ to generate EventFactory and EventNames.
The .json5 format is documented in build/scripts/json5_generator.py.
"""

from optparse import OptionParser
import os
import posixpath
import sys

from utilities import (get_file_contents, get_first_interface_name_from_idl,
                       read_file_to_list, write_file,
                       get_interface_extended_attributes_from_idl)

EXPORTED_EXTENDED_ATTRIBUTES = (
    'ImplementedAs',
    'RuntimeEnabled',
)
module_path = os.path.dirname(os.path.realpath(__file__))
source_dir = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))


def parse_options():
    parser = OptionParser()
    parser.add_option('--event-idl-files-list', help='file listing event IDL files')
    parser.add_option('--event-interfaces-file', help='output file')
    parser.add_option('--suffix', help='specify a suffix to the namespace, i.e., "Modules". Default is None.')

    options, args = parser.parse_args()
    if options.event_idl_files_list is None:
        parser.error('Must specify a file listing event IDL files using --event-idl-files-list.')
    if options.event_interfaces_file is None:
        parser.error('Must specify an output file using --event-interfaces-file.')
    if args:
        parser.error('No arguments allowed, but %d given.' % len(args))
    return options


def write_event_interfaces_file(event_idl_files, destination_filename, suffix):
    def interface_line(full_path):
        relative_dir_local = os.path.dirname(os.path.relpath(full_path, source_dir))
        relative_dir_posix = relative_dir_local.replace(os.sep, posixpath.sep)

        idl_file_contents = get_file_contents(full_path)
        interface_name = get_first_interface_name_from_idl(idl_file_contents)
        extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
        extended_attributes_list = [
            (name, extended_attributes[name])
            for name in EXPORTED_EXTENDED_ATTRIBUTES
            if name in extended_attributes]

        return (posixpath.join(relative_dir_posix, interface_name),
                extended_attributes_list)

    lines = [
        '{',
        'metadata: {',
        '  namespace: "Event",'
    ]
    if suffix:
        lines.append('  suffix: "' + suffix + '",')
        lines.append('  export: "%s_EXPORT",' % suffix.upper())
    else:
        lines.append('  export: "CORE_EXPORT",')
    lines.extend([
        '},',
        'data: ['
    ])
    interface_lines = [interface_line(event_idl_file)
                       for event_idl_file in event_idl_files]
    interface_lines.sort()
    for name, attributes in interface_lines:
        lines.extend([
            '  {',
            '    name: "%s",' % name
        ])
        for param, value in attributes:
            if param == 'RuntimeEnabled':
                value += 'Enabled'
            lines.append('    %s: "%s",' % (param, value))
        lines.append('  },')
    lines.extend([
        ']',
        '}'
    ])
    write_file('\n'.join(lines), destination_filename)


################################################################################

def main():
    options = parse_options()
    event_idl_files = read_file_to_list(options.event_idl_files_list)
    write_event_interfaces_file(event_idl_files,
                                options.event_interfaces_file,
                                options.suffix)


if __name__ == '__main__':
    sys.exit(main())
