#!/usr/bin/env python3
# Copyright (C) 2025 Samuel Weinig <sam@webkit.org>
#
# 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 files for a properties JSON file. Please
# execute the script whenever changes are made to process-css-properties.py,
# and submit the changes to the test results in the same commit. This makes 
# it easier to track and review changes in generated code.

import optparse
import os
import sys
from webkitpy.port.linux_container_sdk_utils import maybe_enter_webkit_container_sdk, maybe_use_container_sdk_root_dir
maybe_enter_webkit_container_sdk()

from webkitpy.common.system import executive
maybe_use_container_sdk_root_dir()

def main(argv):
    """Runs WebCore css property code generator on test input and compares
    the results with reference files.
    """

    option_parser = optparse.OptionParser(usage='run-css-property-code-generation-tests [options] [patterns-to-test...]',
        description="Runs WebCore css property code generator on test input 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.css_properties.main import CSSPropertyCodeGenerationTests

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

    return CSSPropertyCodeGenerationTests(options.reset_results, executive.Executive(), not options.no_verbose, args, options.json_file_name).main()


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