# Copyright (C) 2017 Igalia S.L.
#
# 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.

import logging
import os

from webkitpy.common.webkit_finder import WebKitFinder
from webkitpy.webdriver_tests.webdriver_w3c_executor import WebDriverW3CExecutor
from webkitpy.webdriver_tests.webdriver_test_result import WebDriverTestResult
from webkitpy.webdriver_tests.webdriver_w3c_web_server import WebDriverW3CWebServer

_log = logging.getLogger(__name__)


class WebDriverTestRunnerW3C(object):

    def __init__(self, port, driver, env, expectations):
        self._port = port
        self._driver = driver
        self._env = env
        self._expectations = expectations
        self._results = []
        self._tests_dir = WebKitFinder(self._port.host.filesystem).path_from_webkit_base('WebDriverTests')

        self._server = WebDriverW3CWebServer(self._port)

    def collect_tests(self, tests):
        skipped = [os.path.join(self._tests_dir, test) for test in self._expectations.skipped_tests()]
        relative_tests_dir = os.path.join('imported', 'w3c', 'webdriver', 'tests')
        w3c_tests = []
        if not tests:
            tests = [relative_tests_dir]
        for test in tests:
            subtest = None
            if '::' in test:
                test, subtest = test.split('::')

            if not test.startswith(relative_tests_dir):
                continue

            test_path = os.path.join(self._tests_dir, test)
            if os.path.isdir(test_path):
                w3c_tests.extend(self._scan_directory(test_path, skipped))
            elif self._is_test(test_path) and test_path not in skipped:
                if subtest is not None:
                    w3c_tests.append(test_path + '::' + subtest)
                else:
                    w3c_tests.append(test_path)
        return w3c_tests

    def _is_test(self, test):
        if not os.path.isfile(test):
            return False
        if os.path.splitext(test)[1] != '.py':
            return False
        if os.path.basename(test) in ['conftest.py', '__init__.py']:
            return False
        if os.path.basename(os.path.dirname(test)) == 'support':
            return False
        return True

    def _scan_directory(self, directory, skipped):
        tests = []
        for path in self._port.host.filesystem.files_under(directory):
            if self._is_test(path) and path not in skipped:
                tests.append(path)
        return tests

    def _subtest_name(self, subtest):
        path, test = subtest.split('::', 1)
        return os.path.basename(path) + '::' + test

    def run(self, tests=[]):
        self._server.start()

        executor = WebDriverW3CExecutor(self._driver, self._server, self._env, self._port.get_option('timeout'), self._expectations)
        executor.setup()
        need_restart = False
        try:
            for test in tests:
                test_name = os.path.relpath(test.split('::')[0], self._tests_dir)
                harness_result, test_results = executor.run(test)
                result = WebDriverTestResult(test_name, *harness_result)
                if harness_result[0] == 'OK':
                    for subtest, status, message, backtrace in test_results:
                        result.add_subtest_results(self._subtest_name(subtest), status, message, backtrace)
                        need_restart = need_restart or status in ('FAIL', 'ERROR', 'XFAIL', 'TIMEOUT')
                else:
                    _log.error("Test %s failed:" % test_name)
                    _log.error(harness_result[1])
                    need_restart = True
                self._results.append(result)

                if need_restart:
                    executor.teardown()
                    executor.setup()
        finally:
            executor.teardown()
            self._server.stop()

    def results(self):
        return self._results
