#!/usr/bin/env python
#
# Copyright (c) 2014, 2016 Apple Inc. All rights reserved.
# Copyright (c) 2014 University of Washington. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.

# This script generates JS, Objective C, and C++ bindings for the inspector protocol.
# Generators for individual files are located in the codegen/ directory.

import os
import re
import sys
import string
from string import Template
import optparse
import logging

try:
    import json
except ImportError:
    import simplejson as json

logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR)
log = logging.getLogger('global')

try:
    from codegen import *

# When copying generator files to JavaScriptCore's private headers on Mac,
# the codegen/ module directory is flattened. So, import directly.
except ImportError as e:
    #log.error(e) # Uncomment this to debug early import errors.
    import models
    from models import *
    from generator import *
    from cpp_generator import *
    from objc_generator import *

    from generate_cpp_alternate_backend_dispatcher_header import *
    from generate_cpp_backend_dispatcher_header import *
    from generate_cpp_backend_dispatcher_implementation import *
    from generate_cpp_frontend_dispatcher_header import *
    from generate_cpp_frontend_dispatcher_implementation import *
    from generate_cpp_protocol_types_header import *
    from generate_cpp_protocol_types_implementation import *
    from generate_js_backend_commands import *
    from generate_objc_backend_dispatcher_header import *
    from generate_objc_backend_dispatcher_implementation import *
    from generate_objc_configuration_header import *
    from generate_objc_configuration_implementation import *
    from generate_objc_frontend_dispatcher_implementation import *
    from generate_objc_header import *
    from generate_objc_internal_header import *
    from generate_objc_protocol_type_conversions_header import *
    from generate_objc_protocol_type_conversions_implementation import *
    from generate_objc_protocol_types_implementation import *


# A writer that only updates file if it actually changed.
class IncrementalFileWriter:
    def __init__(self, filepath, force_output):
        self._filepath = filepath
        self._output = ""
        self.force_output = force_output

    def write(self, text):
        self._output += text

    def close(self):
        text_changed = True
        self._output = self._output.rstrip() + "\n"

        try:
            if self.force_output:
                raise

            read_file = open(self._filepath, "r")
            old_text = read_file.read()
            read_file.close()
            text_changed = old_text != self._output
        except:
            # Ignore, just overwrite by default
            pass

        if text_changed or self.force_output:
            dirname = os.path.dirname(self._filepath)
            if not os.path.isdir(dirname):
                os.makedirs(dirname)
            out_file = open(self._filepath, "w")
            out_file.write(self._output)
            out_file.close()


def generate_from_specification(primary_specification_filepath=None,
                                supplemental_specification_filepaths=[],
                                concatenate_output=False,
                                output_dirpath=None,
                                force_output=False,
                                framework_name="",
                                generate_frontend=True,
                                generate_backend=True):

    def load_specification(protocol, filepath, isSupplemental=False):
        try:
            with open(filepath, "r") as input_file:
                regex = re.compile(r"\/\*.*?\*\/", re.DOTALL)
                parsed_json = json.loads(re.sub(regex, "", input_file.read()))
                protocol.parse_specification(parsed_json, isSupplemental)
        except ValueError as e:
            raise Exception("Error parsing valid JSON in file: " + filepath + "\nParse error: " + str(e))

    protocol = models.Protocol(framework_name)
    for specification in supplemental_specification_filepaths:
        load_specification(protocol, specification, isSupplemental=True)
    load_specification(protocol, primary_specification_filepath, isSupplemental=False)

    protocol.resolve_types()

    generator_arguments = [protocol, primary_specification_filepath]
    generators = []

    if protocol.framework is Frameworks.Test:
        generators.append(JSBackendCommandsGenerator(*generator_arguments))
        generators.append(CppAlternateBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppBackendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppProtocolTypesHeaderGenerator(*generator_arguments))
        generators.append(CppProtocolTypesImplementationGenerator(*generator_arguments))
        generators.append(ObjCBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(ObjCBackendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(ObjCConfigurationHeaderGenerator(*generator_arguments))
        generators.append(ObjCConfigurationImplementationGenerator(*generator_arguments))
        generators.append(ObjCFrontendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(ObjCHeaderGenerator(*generator_arguments))
        generators.append(ObjCInternalHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypeConversionsHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypeConversionsImplementationGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypesImplementationGenerator(*generator_arguments))

    elif protocol.framework is Frameworks.JavaScriptCore:
        generators.append(CppAlternateBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppBackendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppProtocolTypesHeaderGenerator(*generator_arguments))
        generators.append(CppProtocolTypesImplementationGenerator(*generator_arguments))

    elif protocol.framework is Frameworks.WebKit and generate_backend:
        generators.append(CppBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppBackendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(CppFrontendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(CppProtocolTypesHeaderGenerator(*generator_arguments))
        generators.append(CppProtocolTypesImplementationGenerator(*generator_arguments))

    elif protocol.framework is Frameworks.WebKit and generate_frontend:
        generators.append(ObjCHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypeConversionsHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypeConversionsImplementationGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypesImplementationGenerator(*generator_arguments))

    elif protocol.framework is Frameworks.WebInspector:
        generators.append(ObjCBackendDispatcherHeaderGenerator(*generator_arguments))
        generators.append(ObjCBackendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(ObjCConfigurationHeaderGenerator(*generator_arguments))
        generators.append(ObjCConfigurationImplementationGenerator(*generator_arguments))
        generators.append(ObjCFrontendDispatcherImplementationGenerator(*generator_arguments))
        generators.append(ObjCHeaderGenerator(*generator_arguments))
        generators.append(ObjCInternalHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypeConversionsHeaderGenerator(*generator_arguments))
        generators.append(ObjCProtocolTypesImplementationGenerator(*generator_arguments))

    elif protocol.framework is Frameworks.WebInspectorUI:
        generators.append(JSBackendCommandsGenerator(*generator_arguments))

    single_output_file_contents = []

    for generator in generators:
        # Only some generators care whether frontend or backend was specified, but it is
        # set on all of them to avoid adding more constructor arguments or thinking too hard.
        if generate_backend:
            generator.set_generator_setting('generate_backend', True)
        if generate_frontend:
            generator.set_generator_setting('generate_frontend', True)

        output = generator.generate_output()
        if concatenate_output:
            single_output_file_contents.append('### Begin File: %s' % generator.output_filename())
            single_output_file_contents.append(output)
            single_output_file_contents.append('### End File: %s' % generator.output_filename())
            single_output_file_contents.append('')
        else:
            output_file = IncrementalFileWriter(os.path.join(output_dirpath, generator.output_filename()), force_output)
            output_file.write(output)
            output_file.close()

    if concatenate_output:
        filename = os.path.join(os.path.basename(primary_specification_filepath) + '-result')
        output_file = IncrementalFileWriter(os.path.join(output_dirpath, filename), force_output)
        output_file.write('\n'.join(single_output_file_contents))
        output_file.close()


if __name__ == '__main__':
    allowed_framework_names = ['JavaScriptCore', 'WebInspector', 'WebInspectorUI', 'WebKit', 'Test']
    cli_parser = optparse.OptionParser(usage="usage: %prog [options] PrimaryProtocol.json [SupplementalProtocol.json ...]")
    cli_parser.add_option("-o", "--outputDir", help="Directory where generated files should be written.")
    cli_parser.add_option("--framework", type="choice", choices=allowed_framework_names, help="The framework that the primary specification belongs to.")
    cli_parser.add_option("--force", action="store_true", help="Force output of generated scripts, even if nothing changed.")
    cli_parser.add_option("-v", "--debug", action="store_true", help="Log extra output for debugging the generator itself.")
    cli_parser.add_option("-t", "--test", action="store_true", help="Enable test mode. Use unique output filenames created by prepending the input filename.")
    cli_parser.add_option("--frontend", action="store_true", help="Generate code for the frontend-side of the protocol only.")
    cli_parser.add_option("--backend", action="store_true", help="Generate code for the backend-side of the protocol only.")
    options = None

    arg_options, arg_values = cli_parser.parse_args()
    if (len(arg_values) < 1):
        raise ParseException("At least one plain argument expected")

    if not arg_options.outputDir:
        raise ParseException("Missing output directory")

    if arg_options.debug:
        log.setLevel(logging.DEBUG)

    generate_backend = arg_options.backend;
    generate_frontend = arg_options.frontend;
    # Default to generating both the frontend and backend if neither is specified.
    if not generate_backend and not generate_frontend:
        generate_backend = True
        generate_frontend = True

    options = {
        'primary_specification_filepath': arg_values[0],
        'supplemental_specification_filepaths': arg_values[1:],
        'output_dirpath': arg_options.outputDir,
        'concatenate_output': arg_options.test,
        'framework_name': arg_options.framework,
        'force_output': arg_options.force,
        'generate_backend': generate_backend,
        'generate_frontend': generate_frontend,
    }

    try:
        generate_from_specification(**options)
    except (ParseException, TypecheckException) as e:
        if arg_options.test:
            log.error(e.message)
        else:
            raise  # Force the build to fail.
