#!/usr/bin/env python
# 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

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))
