# Copyright (C) 2011 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.
#

import fnmatch
import json
import os
import os.path
import shutil
import sys
import tempfile

from webkitcorepy import string_utils

from webkitpy.common.checkout.scm.detection import detect_scm_system
from webkitpy.common.system.executive import ScriptError


class BindingsTests:

    def __init__(self, reset_results, generators, executive, verbose, patterns, json_file_name):
        self.reset_results = reset_results
        self.generators = generators
        self.executive = executive
        self.verbose = verbose
        self.patterns = patterns
        self.json_file_name = json_file_name

        if self.json_file_name:
            self.failures = []

    def generate_from_idl(self, generator, idl_file, output_directory, supplemental_dependency_file):
        cmd = ['perl', '-w',
               '-IWebCore/bindings/scripts',
               'WebCore/bindings/scripts/generate-bindings.pl',
               # idl include directories (path relative to generate-bindings.pl)
               '--include', '.',
               '--defines', 'TESTING_%s' % generator,
               '--generator', generator,
               '--outputDir', output_directory,
               '--supplementalDependencyFile', supplemental_dependency_file,
               '--idlAttributesFile', 'WebCore/bindings/scripts/IDLAttributes.json',
               idl_file]

        exit_code = 0
        try:
            output = self.executive.run_command(cmd)
            if output:
                print(output)
        except ScriptError as e:
            print(e.output)
            exit_code = e.exit_code
        return exit_code

    def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file, supplemental_makefile_dependency_file, window_constructors_file, workerglobalscope_constructors_file, shadowrealmglobalscope_constructors_file, dedicatedworkerglobalscope_constructors_file, serviceworkerglobalscope_constructors_file, sharedworkerglobalscope_constructors_file, workletglobalscope_constructors_file, paintworkletglobalscope_constructors_file, audioworkletglobalscope_constructors_file, testglobalscope_constructors_file):
        idl_files_list = tempfile.mkstemp()
        for input_file in os.listdir(input_directory):
            (name, extension) = os.path.splitext(input_file)
            if extension != '.idl':
                continue
            if name.endswith('Constructors'):
                continue
            os.write(idl_files_list[0], string_utils.encode(os.path.join(input_directory, input_file) + "\n"))
        os.close(idl_files_list[0])

        cmd = ['perl', '-w',
               '-IWebCore/bindings/scripts',
               'WebCore/bindings/scripts/preprocess-idls.pl',
               '--idlFileNamesList', idl_files_list[1],
               '--testGlobalContextName', 'TestGlobalObject',
               '--defines', '',
               '--idlAttributesFile', 'WebCore/bindings/scripts/IDLAttributes.json',
               '--supplementalDependencyFile', supplemental_dependency_file,
               '--supplementalMakefileDeps', supplemental_makefile_dependency_file,
               '--windowConstructorsFile', window_constructors_file,
               '--workerGlobalScopeConstructorsFile', workerglobalscope_constructors_file,
               '--shadowRealmGlobalScopeConstructorsFile', shadowrealmglobalscope_constructors_file,
               '--dedicatedWorkerGlobalScopeConstructorsFile', dedicatedworkerglobalscope_constructors_file,
               '--serviceWorkerGlobalScopeConstructorsFile', serviceworkerglobalscope_constructors_file,
               '--sharedWorkerGlobalScopeConstructorsFile', sharedworkerglobalscope_constructors_file,
               '--workletGlobalScopeConstructorsFile', workletglobalscope_constructors_file,
               '--paintWorkletGlobalScopeConstructorsFile', paintworkletglobalscope_constructors_file,
               '--audioWorkletGlobalScopeConstructorsFile', audioworkletglobalscope_constructors_file,
               '--testGlobalScopeConstructorsFile', testglobalscope_constructors_file,
               '--validateAgainstParser']

        exit_code = 0
        try:
            output = self.executive.run_command(cmd)
            if output:
                print(output)
        except ScriptError as e:
            print(e.output)
            exit_code = e.exit_code
        os.remove(idl_files_list[1])
        return exit_code

    def detect_changes(self, generator, work_directory, reference_directory):
        changes_found = False
        for filename in os.listdir(work_directory):
            if self.detect_file_changes(generator, work_directory, reference_directory, filename):
                changes_found = True
        return changes_found

    def detect_file_changes(self, generator, work_directory, reference_directory, filename):
        changes_found = False
        cmd = ['diff',
               '-u',
               '-N',
               os.path.join(reference_directory, filename),
               os.path.join(work_directory, filename)]

        exit_code = 0
        try:
            output = self.executive.run_command(cmd)
        except ScriptError as e:
            output = e.output
            exit_code = e.exit_code

        if exit_code or output:
            print('FAIL: (%s) %s' % (generator, filename))
            print(output)
            changes_found = True
            if self.json_file_name:
                self.failures.append("(%s) %s" % (generator, filename))
        elif self.verbose:
            print('PASS: (%s) %s' % (generator, filename))
        sys.stdout.flush()
        return changes_found

    def test_matches_patterns(self, test):
        if not self.patterns:
            return True
        for pattern in self.patterns:
            if fnmatch.fnmatch(test, pattern):
                return True
        return False

    def run_tests(self, generator, input_directory, reference_directory, supplemental_dependency_file):
        work_directory = reference_directory

        passed = True
        for input_file in os.listdir(input_directory):
            (name, extension) = os.path.splitext(input_file)
            if extension != '.idl':
                continue

            if not self.test_matches_patterns(input_file):
                continue

            # Generate output into the work directory (either the given one or a
            # temp one if not reset_results is performed)
            if not self.reset_results:
                work_directory = tempfile.mkdtemp()

            if self.generate_from_idl(generator,
                                      os.path.join(input_directory, input_file),
                                      work_directory,
                                      supplemental_dependency_file):
                passed = False

            if self.reset_results:
                print("Reset results: (%s) %s" % (generator, input_file))
                continue

            # Detect changes
            if self.detect_changes(generator, work_directory, reference_directory):
                passed = False
            shutil.rmtree(work_directory)

        return passed

    def main(self):
        current_scm = detect_scm_system(os.path.dirname(__file__))
        os.chdir(os.path.join(current_scm.checkout_root, 'Source'))

        all_tests_passed = True

        supplemental_dependency_filename = 'SupplementalDependencies.txt'
        supplemental_makefile_dependency_filename = 'SupplementalDependencies.dep'
        dom_window_constructors_filename = 'DOMWindowConstructors.idl'
        workerglobalscope_constructors_filename = 'WorkerGlobalScopeConstructors.idl'
        shadowrealmglobalscope_constructors_filename = 'ShadowRealmGlobalScopeConstructors.idl'
        dedicatedworkerglobalscope_constructors_filename = 'DedicatedWorkerGlobalScopeConstructors.idl'
        serviceworkerglobalscope_constructors_filename = 'ServiceWorkerGlobalScopeConstructors.idl'
        sharedworkerglobalscope_constructors_filename = 'SharedWorkerGlobalScopeConstructors.idl'
        workletglobalscope_constructors_filename = 'WorkletGlobalScopeConstructors.idl'
        paintworkletglobalscope_constructors_filename = 'PaintWorkletGlobalScopeConstructors.idl'
        audioworkletglobalscope_constructors_filename = 'AudioWorkletGlobalScopeConstructors.idl'
        testglobalscope_constructors_filename = 'BindingTestGlobalConstructors.idl'

        work_directory = tempfile.mkdtemp()
        input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
        supplemental_dependency_file = os.path.join(work_directory, supplemental_dependency_filename)
        supplemental_makefile_dependency_file = os.path.join(work_directory if not self.reset_results else input_directory, supplemental_makefile_dependency_filename)
        window_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, dom_window_constructors_filename)
        workerglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, workerglobalscope_constructors_filename)
        shadowrealmglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, shadowrealmglobalscope_constructors_filename)
        dedicatedworkerglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, dedicatedworkerglobalscope_constructors_filename)
        serviceworkerglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, serviceworkerglobalscope_constructors_filename)
        sharedworkerglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, sharedworkerglobalscope_constructors_filename)
        workletglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, workletglobalscope_constructors_filename)
        paintworkletglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, paintworkletglobalscope_constructors_filename)
        audioworkletglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, audioworkletglobalscope_constructors_filename)
        testglobalscope_constructors_file = os.path.join(work_directory if not self.reset_results else input_directory, testglobalscope_constructors_filename)

        if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file, supplemental_makefile_dependency_file, window_constructors_file, workerglobalscope_constructors_file, shadowrealmglobalscope_constructors_file, dedicatedworkerglobalscope_constructors_file, serviceworkerglobalscope_constructors_file, sharedworkerglobalscope_constructors_file, workletglobalscope_constructors_file, paintworkletglobalscope_constructors_file, audioworkletglobalscope_constructors_file, testglobalscope_constructors_file):
            print('Failed to generate a supplemental dependency file.')
            shutil.rmtree(work_directory)
            return -1

        if not self.reset_results:
            if self.detect_file_changes('dependencies', work_directory, input_directory, supplemental_makefile_dependency_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, dom_window_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, workerglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, shadowrealmglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, dedicatedworkerglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, serviceworkerglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, sharedworkerglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, workletglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, paintworkletglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, audioworkletglobalscope_constructors_filename):
                all_tests_passed = False
            if self.detect_file_changes('globalscope', work_directory, input_directory, testglobalscope_constructors_filename):
                all_tests_passed = False

        for generator in self.generators:
            input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
            reference_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test', generator)
            if not self.run_tests(generator, input_directory, reference_directory, supplemental_dependency_file):
                all_tests_passed = False

        shutil.rmtree(work_directory)

        if self.json_file_name:
            json_data = {
                'failures': self.failures,
            }

            with open(self.json_file_name, 'w') as json_file:
                json.dump(json_data, json_file)

        print('')
        if all_tests_passed:
            print('All tests PASS!')
            return 0
        else:
            print('Some tests FAIL! (To update the reference files, execute "run-bindings-tests --reset-results")')
            return -1
