# 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:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * 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.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
# OWNER 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 logging

from webkitpy.layout_tests.layout_package.bot_test_expectations import BotTestExpectationsFactory
from webkitpy.layout_tests.models.test_expectations import TestExpectations
from webkitpy.layout_tests.models.test_expectations import TestExpectationsModel
from webkitpy.tool.commands.command import Command


_log = logging.getLogger(__name__)


class FlakyTests(Command):
    name = 'print-flaky-tests'
    help_text = 'Print out flaky tests based on results from the flakiness dashboard'
    show_in_main_help = True

    FLAKINESS_DASHBOARD_URL = 'https://test-results.appspot.com/dashboards/flakiness_dashboard.html#testType=webkit_tests&tests=%s'

    BUG_TEMPLATE = (
        'https://code.google.com/p/chromium/issues/entry?owner=FILL_ME_IN&status=Assigned&'
        'labels=Pri-1,Cr-Blink,FlakyLayoutTest&summary=XXXXXXX%20is%20flaky&'
        'comment=XXXXXXX%20is%20flaky.%0A%0AIt%20failed%20twice%20and%20then'
        '%20passed%20on%20the%203rd%20or%204th%20retry.%20This%20is%20too%20'
        'flaky.%20The%20test%20will%20be%20skipped%20until%20it%27s%20fixed.'
        '%20If%20not%20fixed%20in%203%20months,%20it%20will%20be%20deleted%20'
        'or%20perma-skipped.%0A%0AIn%20the%20flakiness%20dashboard,%20the%20'
        'turquoise%20boxes%20are%20runs%20where%20the%20test%20failed%20and%20'
        'then%20passed%20on%20retry.%0A%0Ahttps://test-results.appspot.com'
        '/dashboards/flakiness_dashboard.html%23tests=XXXXXXX')

    HEADER = (
        'Manually add bug numbers for these and then put the lines in LayoutTests/TestExpectations.\n'
        'Look up the test in the flakiness dashboard first to see if the the platform\n'
        'specifiers should be made more general.\n\n'
        'Bug template:\n%s\n') % BUG_TEMPLATE

    OUTPUT = '%s\n%s\n\nFlakiness dashboard: %s\n'

    def __init__(self):
        super(FlakyTests, self).__init__()
        # This is sorta silly, but allows for unit testing:
        self.expectations_factory = BotTestExpectationsFactory

    def _filter_build_type_specifiers(self, specifiers):
        filtered = []
        for specifier in specifiers:
            if specifier.lower() not in TestExpectations.BUILD_TYPES:
                filtered.append(specifier)
        return filtered

    def _collect_expectation_lines(self, builder_names, factory):
        models = []
        for builder_name in builder_names:
            model = TestExpectationsModel()
            models.append(model)

            expectations = factory.expectations_for_builder(builder_name)

            # TODO(ojan): We should also skip bots that haven't uploaded recently,
            # e.g. if they're >24h stale.
            if not expectations:
                _log.error("Can't load flakiness data for builder: %s", builder_name)
                continue

            for line in expectations.expectation_lines(only_ignore_very_flaky=True):
                # TODO(ojan): Find a way to merge specifiers instead of removing build types.
                # We can't just union because some specifiers will change the meaning of others.
                # For example, it's not clear how to merge [ Mac Release ] with [ Linux Debug ].
                # But, in theory we should be able to merge [ Mac Release ] and [ Mac Debug ].
                line.specifiers = self._filter_build_type_specifiers(line.specifiers)
                model.add_expectation_line(line)

        final_model = None
        for model in models:
            if final_model:
                final_model.merge_model(model)
            else:
                final_model = model
        return final_model._test_to_expectation_line.values()

    def execute(self, options, args, tool):
        factory = self.expectations_factory(tool.builders)
        lines = self._collect_expectation_lines(tool.builders.all_continuous_builder_names(), factory)
        lines.sort(key=lambda line: line.path)

        port = tool.port_factory.get()
        # Skip any tests which are mentioned in the dashboard but not in our checkout:
        fs = tool.filesystem
        lines = [line for line in lines if fs.exists(fs.join(port.layout_tests_dir(), line.path))]

        test_names = [line.name for line in lines]
        flakiness_dashboard_url = self.FLAKINESS_DASHBOARD_URL % ','.join(test_names)
        expectations_string = TestExpectations.list_to_string(lines)

        print self.OUTPUT % (self.HEADER, expectations_string, flakiness_dashboard_url)
