# Copyright (c) 2009 Google Inc. All rights reserved.
# Copyright (c) 2009 Apple Inc. All rights reserved.
# Copyright (c) 2012 Intel Corporation. All rights reserved.
# Copyright (c) 2013 University of Szeged. 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.

from __future__ import print_function
import fnmatch
import logging
import re

from datetime import datetime
from optparse import make_option

from webkitpy.tool import steps

from webkitpy.common.checkout.commitinfo import CommitInfo
from webkitpy.common.config.committers import CommitterList
import webkitpy.common.config.urls as config_urls
from webkitpy.common.net.buildbot import BuildBot
from webkitpy.common.net.bugzilla import Bugzilla
from webkitpy.common.net.regressionwindow import RegressionWindow
from webkitpy.common.system.crashlogs import CrashLogs
from webkitpy.common.system.user import User
from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
from webkitpy.tool.grammar import pluralize
from webkitpy.tool.multicommandtool import Command
from webkitpy.layout_tests.models.test_expectations import TestExpectations
from webkitpy.port import platform_options, configuration_options

_log = logging.getLogger(__name__)


class SuggestReviewers(AbstractSequencedCommand):
    name = "suggest-reviewers"
    help_text = "Suggest reviewers for a patch based on recent changes to the modified files."
    steps = [
        steps.SuggestReviewers,
    ]

    def _prepare_state(self, options, args, tool):
        options.suggest_reviewers = True


class BugsToCommit(Command):
    name = "bugs-to-commit"
    help_text = "List bugs in the commit-queue"

    def execute(self, options, args, tool):
        # FIXME: This command is poorly named.  It's fetching the commit-queue list here.  The name implies it's fetching pending-commit (all r+'d patches).
        bug_ids = tool.bugs.queries.fetch_bug_ids_from_commit_queue()
        for bug_id in bug_ids:
            print("%s" % bug_id)


class PatchesInCommitQueue(Command):
    name = "patches-in-commit-queue"
    help_text = "List patches in the commit-queue"

    def execute(self, options, args, tool):
        patches = tool.bugs.queries.fetch_patches_from_commit_queue()
        _log.info("Patches in commit queue:")
        for patch in patches:
            print(patch.url())


class PatchesToCommitQueue(Command):
    name = "patches-to-commit-queue"
    help_text = "Patches which should be added to the commit queue"

    def __init__(self):
        options = [
            make_option("--bugs", action="store_true", dest="bugs", help="Output bug links instead of patch links"),
        ]
        Command.__init__(self, options=options)

    @staticmethod
    def _needs_commit_queue(patch):
        if patch.commit_queue() == "+":  # If it's already cq+, ignore the patch.
            _log.info("%s already has cq=%s" % (patch.id(), patch.commit_queue()))
            return False

        # We only need to worry about patches from contributers who are not yet committers.
        committer_record = CommitterList().committer_by_email(patch.attacher_email())
        if committer_record:
            _log.info("%s committer = %s" % (patch.id(), committer_record))
        return not committer_record

    def execute(self, options, args, tool):
        patches = tool.bugs.queries.fetch_patches_from_pending_commit_list()
        patches_needing_cq = filter(self._needs_commit_queue, patches)
        if options.bugs:
            bugs_needing_cq = map(lambda patch: patch.bug_id(), patches_needing_cq)
            bugs_needing_cq = sorted(set(bugs_needing_cq))
            for bug_id in bugs_needing_cq:
                print("%s" % tool.bugs.bug_url_for_bug_id(bug_id))
        else:
            for patch in patches_needing_cq:
                print("%s" % tool.bugs.attachment_url_for_id(patch.id(), action="edit"))


class PatchesToReview(Command):
    name = "patches-to-review"
    help_text = "List bugs which have attachments pending review"

    def __init__(self):
        options = [
            make_option("--all", action="store_true",
                        help="Show all bugs regardless of who is on CC (it might take a while)"),
            make_option("--include-cq-denied", action="store_true",
                        help="By default, r? patches with cq- are omitted unless this option is set"),
            make_option("--cc-email",
                        help="Specifies the email on the CC field (defaults to your bugzilla login email)"),
        ]
        Command.__init__(self, options=options)

    def _print_report(self, report, cc_email, print_all):
        if print_all:
            print("Bugs with attachments pending review:")
        else:
            print("Bugs with attachments pending review that has %s in the CC list:" % cc_email)

        print("http://webkit.org/b/bugid   Description (age in days)")
        for row in report:
            print("%s (%d)" % (row[1], row[0]))

        print("Total: %d" % len(report))

    def _generate_report(self, bugs, include_cq_denied):
        report = []

        for bug in bugs:
            patch = bug.unreviewed_patches()[-1]

            if not include_cq_denied and patch.commit_queue() == "-":
                continue

            age_in_days = (datetime.today() - patch.attach_date()).days
            report.append((age_in_days, "http://webkit.org/b/%-7s %s" % (bug.id(), bug.title())))

        report.sort()
        return report

    def execute(self, options, args, tool):
        tool.bugs.authenticate()

        cc_email = options.cc_email
        if not cc_email and not options.all:
            cc_email = tool.bugs.username

        bugs = tool.bugs.queries.fetch_bugs_from_review_queue(cc_email=cc_email)
        report = self._generate_report(bugs, options.include_cq_denied)
        self._print_report(report, cc_email, options.all)


class WhatBroke(Command):
    name = "what-broke"
    help_text = "Print failing buildbots (%s) and what revisions broke them" % config_urls.buildbot_url

    def _print_builder_line(self, builder_name, max_name_width, status_message):
        print("%s : %s" % (builder_name.ljust(max_name_width), status_message))

    def _print_blame_information_for_builder(self, builder_status, name_width, avoid_flakey_tests=True):
        builder = self._tool.buildbot.builder_with_name(builder_status["name"])
        red_build = builder.build(builder_status["build_number"])
        regression_window = builder.find_regression_window(red_build)
        if not regression_window.failing_build():
            self._print_builder_line(builder.name(), name_width, "FAIL (error loading build information)")
            return
        if not regression_window.build_before_failure():
            self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: sometime before %s?)" % regression_window.failing_build().revision())
            return

        revisions = regression_window.revisions()
        first_failure_message = ""
        if (regression_window.failing_build() == builder.build(builder_status["build_number"])):
            first_failure_message = " FIRST FAILURE, possibly a flaky test"
        self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: %s%s)" % (revisions, first_failure_message))
        for revision in revisions:
            commit_info = self._tool.checkout().commit_info_for_revision(revision)
            if commit_info:
                print(commit_info.blame_string(self._tool.bugs))
            else:
                print("FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision)

    def execute(self, options, args, tool):
        builder_statuses = tool.buildbot.builder_statuses()
        longest_builder_name = max(map(len, map(lambda builder: builder["name"], builder_statuses)))
        failing_builders = 0
        for builder_status in builder_statuses:
            # If the builder is green, print OK, exit.
            if builder_status["is_green"]:
                continue
            self._print_blame_information_for_builder(builder_status, name_width=longest_builder_name)
            failing_builders += 1
        if failing_builders:
            print("%s of %s are failing" % (failing_builders, pluralize(len(builder_statuses), "builder")))
        else:
            print("All builders are passing!")


class ResultsFor(Command):
    name = "results-for"
    help_text = "Print a list of failures for the passed revision from bots on %s" % config_urls.buildbot_url
    argument_names = "REVISION"

    def _print_layout_test_results(self, results):
        if not results:
            print(" No results.")
            return
        for title, files in results.parsed_results().items():
            print(" %s" % title)
            for filename in files:
                print("  %s" % filename)

    def execute(self, options, args, tool):
        builders = self._tool.buildbot.builders()
        for builder in builders:
            print("%s:" % builder.name())
            build = builder.build_for_revision(args[0], allow_failed_lookups=True)
            self._print_layout_test_results(build.layout_test_results())


class FailureReason(Command):
    name = "failure-reason"
    help_text = "Lists revisions where individual test failures started at %s" % config_urls.buildbot_url
    arguments_names = "[LAYOUT_TESTS]"

    def _blame_line_for_revision(self, revision):
        try:
            commit_info = self._tool.checkout().commit_info_for_revision(revision)
        except Exception as e:
            return "FAILED to fetch CommitInfo for r%s, exception: %s" % (revision, e)
        if not commit_info:
            return "FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision
        return commit_info.blame_string(self._tool.bugs)

    def _print_blame_information_for_transition(self, regression_window, failing_tests):
        red_build = regression_window.failing_build()
        print("SUCCESS: Build %s (r%s) was the first to show failures: %s" % (red_build._number, red_build.revision(), failing_tests))
        print("Suspect revisions:")
        for revision in regression_window.revisions():
            print(self._blame_line_for_revision(revision))

    def _explain_failures_for_builder(self, builder, start_revision):
        print("Examining failures for \"%s\", starting at r%s" % (builder.name(), start_revision))
        revision_to_test = start_revision
        build = builder.build_for_revision(revision_to_test, allow_failed_lookups=True)
        layout_test_results = build.layout_test_results()
        if not layout_test_results:
            # FIXME: This could be made more user friendly.
            print("Failed to load layout test results from %s; can't continue. (start revision = r%s)" % (build.results_url(), start_revision))
            return 1

        results_to_explain = set(layout_test_results.failing_tests())
        last_build_with_results = build
        print("Starting at %s" % revision_to_test)
        while results_to_explain and not self._done_explaining():
            revision_to_test -= 1
            new_build = builder.build_for_revision(revision_to_test, allow_failed_lookups=True)
            if not new_build:
                print("No build for %s" % revision_to_test)
                continue
            build = new_build
            latest_results = build.layout_test_results()
            if not latest_results:
                print("No results build %s (r%s)" % (build._number, build.revision()))
                continue
            failures = set(latest_results.failing_tests())
            if len(failures) >= 500:
                # FIXME: We may need to move this logic into the LayoutTestResults class.
                # The buildbot stops runs after 500 failures so we don't have full results to work with here.
                print("Too many failures in build %s (r%s), ignoring." % (build._number, build.revision()))
                continue
            fixed_results = results_to_explain - failures
            if not fixed_results:
                print("No change in build %s (r%s), %s unexplained failures (%s in this build)" % (build._number, build.revision(), len(results_to_explain), len(failures)))
                last_build_with_results = build
                continue
            self.explained_failures.update(fixed_results)
            regression_window = RegressionWindow(build, last_build_with_results)
            self._print_blame_information_for_transition(regression_window, fixed_results)
            last_build_with_results = build
            results_to_explain -= fixed_results
        if results_to_explain:
            print("Failed to explain failures: %s" % results_to_explain)
            return 1
        print("Explained all results for %s" % builder.name())
        return 0

    def _builder_to_explain(self):
        builder_statuses = self._tool.buildbot.builder_statuses()
        red_statuses = [status for status in builder_statuses if not status["is_green"]]
        print("%s failing" % (pluralize(len(red_statuses), "builder")))
        builder_choices = [status["name"] for status in red_statuses]
        # We could offer an "All" choice here.
        chosen_name = self._tool.user.prompt_with_list("Which builder to diagnose:", builder_choices)
        # FIXME: prompt_with_list should really take a set of objects and a set of names and then return the object.
        for status in red_statuses:
            if status["name"] == chosen_name:
                return (self._tool.buildbot.builder_with_name(chosen_name), status["built_revision"])

    def _done_explaining(self):
        if not self.failures_to_explain:
            return False

        return self.explained_failures.issuperset(self.failures_to_explain)

    def execute(self, options, args, tool):
        (builder, latest_revision) = self._builder_to_explain()
        start_revision = self._tool.user.prompt("Revision to walk backwards from? [%s] " % latest_revision) or latest_revision
        self.failures_to_explain = args
        self.explained_failures = set()
        if not start_revision:
            print("Revision required.")
            return 1
        return self._explain_failures_for_builder(builder, start_revision=int(start_revision))


class FindFlakyTests(Command):
    name = "find-flaky-tests"
    help_text = "Lists tests that often fail for a single build at %s" % config_urls.buildbot_url

    def _find_failures(self, builder, revision):
        build = builder.build_for_revision(revision, allow_failed_lookups=True)
        if not build:
            print("No build for %s" % revision)
            return (None, None)
        results = build.layout_test_results()
        if not results:
            print("No results build %s (r%s)" % (build._number, build.revision()))
            return (None, None)
        failures = set(results.failing_tests())
        if len(failures) >= 20:
            # FIXME: We may need to move this logic into the LayoutTestResults class.
            # The buildbot stops runs after 20 failures so we don't have full results to work with here.
            print("Too many failures in build %s (r%s), ignoring." % (build._number, build.revision()))
            return (None, None)
        return (build, failures)

    def _increment_statistics(self, flaky_tests, flaky_test_statistics):
        for test in flaky_tests:
            count = flaky_test_statistics.get(test, 0)
            flaky_test_statistics[test] = count + 1

    def _print_statistics(self, statistics):
        print("=== Results ===")
        print("Occurrences Test name")
        for value, key in sorted([(value, key) for key, value in statistics.items()]):
            print("%10d %s" % (value, key))

    def _walk_backwards_from(self, builder, start_revision, limit):
        flaky_test_statistics = {}
        all_previous_failures = set([])
        one_time_previous_failures = set([])
        previous_build = None
        for i in range(limit):
            revision = start_revision - i
            print("Analyzing %s ... " % revision, end=' ')
            (build, failures) = self._find_failures(builder, revision)
            if failures == None:
                # Notice that we don't loop on the empty set!
                continue
            print("has %s failures" % len(failures))
            flaky_tests = one_time_previous_failures - failures
            if flaky_tests:
                print("Flaky tests: %s %s" % (sorted(flaky_tests),
                                              previous_build.results_url()))
            self._increment_statistics(flaky_tests, flaky_test_statistics)
            one_time_previous_failures = failures - all_previous_failures
            all_previous_failures = failures
            previous_build = build
        self._print_statistics(flaky_test_statistics)

    def _builder_to_analyze(self):
        statuses = self._tool.buildbot.builder_statuses()
        choices = [status["name"] for status in statuses]
        chosen_name = self._tool.user.prompt_with_list("Which builder to analyze:", choices)
        for status in statuses:
            if status["name"] == chosen_name:
                return (self._tool.buildbot.builder_with_name(chosen_name), status["built_revision"])

    def execute(self, options, args, tool):
        (builder, latest_revision) = self._builder_to_analyze()
        limit = self._tool.user.prompt("How many revisions to look through? [10000] ") or 10000
        return self._walk_backwards_from(builder, latest_revision, limit=int(limit))


class TreeStatus(Command):
    name = "tree-status"
    help_text = "Print the status of the %s buildbots" % config_urls.buildbot_url
    long_help = """Fetches build status from https://build.webkit.org/one_box_per_builder
and displayes the status of each builder."""

    def execute(self, options, args, tool):
        for builder in tool.buildbot.builder_statuses():
            status_string = "ok" if builder["is_green"] else "FAIL"
            print("%s : %s" % (status_string.ljust(4), builder["name"]))


class CrashLog(Command):
    name = "crash-log"
    help_text = "Print the newest crash log for the given process"
    long_help = """Finds the newest crash log matching the given process name
and PID and prints it to stdout."""
    argument_names = "PROCESS_NAME [PID]"

    def execute(self, options, args, tool):
        default_port = tool.port_factory.get()
        crash_logs = CrashLogs(tool, default_port.path_to_crash_logs())
        pid = None
        if len(args) > 1:
            pid = int(args[1])
        print(crash_logs.find_newest_log(args[0], pid))


class PrintExpectations(Command):
    name = 'print-expectations'
    help_text = 'Print the expected result for the given test(s) on the given port(s)'

    def __init__(self):
        options = [
            make_option('--all', action='store_true', default=False,
                        help='display the expectations for *all* tests'),
            make_option('-x', '--exclude-keyword', action='append', default=[],
                        help='limit to tests not matching the given keyword (for example, "skip", "slow", or "crash". May specify multiple times'),
            make_option('-i', '--include-keyword', action='append', default=[],
                        help='limit to tests with the given keyword (for example, "skip", "slow", or "crash". May specify multiple times'),
            make_option('-f', '--full', action='store_true', default=False,
                        help='Print a full TestExpectations-style line for every match'),
            make_option('--paths', action='store_true', default=False,
                        help='display the paths for all applicable expectation files'),
        ] + platform_options(use_globs=True)

        Command.__init__(self, options=options)
        self._expectation_models = {}

    def execute(self, options, args, tool):
        if not options.paths and not args and not options.all:
            print("You must either specify one or more test paths or --all.")
            return

        if options.platform:
            port_names = fnmatch.filter(tool.port_factory.all_port_names(), options.platform)
            if not port_names:
                default_port = tool.port_factory.get(options.platform)
                if default_port:
                    port_names = [default_port.name()]
                else:
                    print("No port names match '%s'" % options.platform)
                    return
            else:
                default_port = tool.port_factory.get(port_names[0])
        else:
            default_port = tool.port_factory.get(options=options)
            port_names = [default_port.name()]

        if options.paths:
            files = default_port.expectations_files()
            layout_tests_dir = default_port.layout_tests_dir()
            for file in files:
                if file.startswith(layout_tests_dir):
                    file = file.replace(layout_tests_dir, 'LayoutTests')
                print(file)
            return

        tests = set(default_port.tests(args))
        for port_name in port_names:
            model = self._model(options, port_name, tests)
            tests_to_print = self._filter_tests(options, model, tests)
            lines = [model.get_expectation_line(test) for test in sorted(tests_to_print)]
            if port_name != port_names[0]:
                print()
            print('\n'.join(self._format_lines(options, port_name, lines)))

    def _filter_tests(self, options, model, tests):
        filtered_tests = set()
        if options.include_keyword:
            for keyword in options.include_keyword:
                filtered_tests.update(model.get_test_set_for_keyword(keyword))
        else:
            filtered_tests = tests

        for keyword in options.exclude_keyword:
            filtered_tests.difference_update(model.get_test_set_for_keyword(keyword))
        return filtered_tests

    def _format_lines(self, options, port_name, lines):
        output = []
        if lines:
            include_modifiers = options.full
            include_expectations = options.full or len(options.include_keyword) != 1 or len(options.exclude_keyword)
            output.append("// For %s" % port_name)
            for line in lines:
                output.append("%s" % line.to_string(None, include_modifiers, include_expectations, include_comment=False))
        return output

    def _model(self, options, port_name, tests):
        port = self._tool.port_factory.get(port_name, options)
        expectations = TestExpectations(port, tests)
        expectations.parse_all_expectations()
        return expectations.model()


class PrintBaselines(Command):
    name = 'print-baselines'
    help_text = 'Prints the baseline locations for given test(s) on the given port(s)'

    def __init__(self):
        options = [
            make_option('--all', action='store_true', default=False,
                        help='display the baselines for *all* tests'),
        ] + platform_options(use_globs=True)
        Command.__init__(self, options=options)
        self._platform_regexp = re.compile('platform/([^\/]+)/(.+)')

    def execute(self, options, args, tool):
        if not args and not options.all:
            print("You must either specify one or more test paths or --all.")
            return

        default_port = tool.port_factory.get()
        if options.platform:
            port_names = fnmatch.filter(tool.port_factory.all_port_names(), options.platform)
            if not port_names:
                print("No port names match '%s'" % options.platform)
        else:
            port_names = [default_port.name()]

        # FIXME: make real_tests() a public method.
        tests = sorted(default_port._real_tests(args))

        for port_name in port_names:
            if port_name != port_names[0]:
                print()
            print("// For %s" % port_name)
            port = tool.port_factory.get(port_name)
            for test_name in tests:
                self._print_baselines(options, port_name, test_name, port.expected_baselines_by_extension(test_name))

    def _print_baselines(self, options, port_name, test_name, baselines):
        for extension in sorted(baselines.keys()):
            baseline_location = baselines[extension]
            if baseline_location:
                print(baseline_location)

    def _platform_for_path(self, relpath):
        platform_matchobj = self._platform_regexp.match(relpath)
        if platform_matchobj:
            return platform_matchobj.group(1)
        return None


class FindResolvedBugs(Command):
    name = "find-resolved-bugs"
    help_text = "Collect the RESOLVED bugs in the given TestExpectations file"
    argument_names = "TEST_EXPECTATIONS_FILE"

    def execute(self, options, args, tool):
        filename = args[0]
        if not tool.filesystem.isfile(filename):
            print("The given path is not a file, please pass a valid path.")
            return

        ids = set()
        inputfile = tool.filesystem.open_text_file_for_reading(filename)
        for line in inputfile:
            result = re.search("(https://bugs\.webkit\.org/show_bug\.cgi\?id=|webkit\.org/b/)([0-9]+)", line)
            if result:
                ids.add(result.group(2))
        inputfile.close()

        resolved_ids = set()
        num_of_bugs = len(ids)
        bugzilla = Bugzilla()
        for i, bugid in enumerate(ids, start=1):
            bug = bugzilla.fetch_bug(bugid)
            print("Checking bug %s \t [%d/%d]" % (bugid, i, num_of_bugs))
            if not bug.is_open():
                resolved_ids.add(bugid)

        print("Resolved bugs in %s :" % (filename))
        for bugid in resolved_ids:
            print("https://bugs.webkit.org/show_bug.cgi?id=%s" % (bugid))
