#!/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="",
                                platform_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))

    platform = Platform.fromString(platform_name)
    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, platform, 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(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))

    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']
    allowed_platform_names = ['iOS', 'macOS', 'all', 'generic']
    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.")
    cli_parser.add_option("--platform", default="generic", help="The platform of the backend being generated. For example, we compile WebKit2 for either macOS or iOS. This value is case-insensitive. Allowed values: %s" % ", ".join(allowed_platform_names))
    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,
        'platform_name': arg_options.platform,
        '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.
