#!/usr/bin/env python3
# Copyright (C) 2010 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:
# 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. ``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
# 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 h and cpp file for TestObj.idl using code
# generators. Please execute the script whenever changes are made to
# CodeGeneratorXXXX.pm, and submit the changes in XXXXTestObj.h/cpp in the same
# patch. This makes it easier to track and review changes in generated code.

import optparse
import os
import sys
from webkitpy.common.system import executive

if sys.platform.startswith('linux'):
    top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..'))
    sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'flatpak'))

    import flatpakutils
    flatpakutils.run_in_sandbox_if_available(sys.argv)

def main(argv):
    """Runs WebCore bindings code generators on test IDL files and compares
    the results with reference files.
    """

    option_parser = optparse.OptionParser(usage='run-bindings-test [options] [patterns-to-test...]',
        description="Runs WebCore bindings code generators on test IDL files and compares the results with reference files")
    option_parser.add_option('--no-verbose', action='store_true', default=False,
        help='Disable verobse output')
    option_parser.add_option('--reset-results', action='store_true', default=False,
        help='Overwrites the reference files with the generated results')
    option_parser.add_option('--json-output', action='store', type='string', dest='json_file_name',
        help='Create a file at specified path, listing test results in JSON format.')
    options, args = option_parser.parse_args()    

    from webkitpy.bindings.main import BindingsTests

    if options.json_file_name:
        options.json_file_name = os.path.abspath(options.json_file_name)

    return BindingsTests(options.reset_results, [ 'JS' ], executive.Executive(), not options.no_verbose, args, options.json_file_name).main()


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