#!/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:
                parsed_json = json.load(input_file)
                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.
