# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Sends notifications after automatic imports (WIP).

Automatically file bugs for new failures caused by WPT imports for opted-in
directories.

Design doc: https://docs.google.com/document/d/1W3V81l94slAC_rPcTKWXgv3YxRxtlSIAxi3yj6NsbBw/edit?usp=sharing

During the implementation phase, we do not open bugs but log everything instead.
"""

from collections import defaultdict
import logging
import re

from blinkpy.common.net.luci_auth import LuciAuth
from blinkpy.common.path_finder import PathFinder
from blinkpy.w3c.common import WPT_GH_URL
from blinkpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor
from blinkpy.w3c.monorail import MonorailAPI, MonorailIssue
from blinkpy.w3c.wpt_expectations_updater import UMBRELLA_BUG

_log = logging.getLogger(__name__)

GITHUB_COMMIT_PREFIX = WPT_GH_URL + 'commit/'
SHORT_GERRIT_PREFIX = 'https://crrev.com/c/'


class ImportNotifier(object):

    def __init__(self, host, chromium_git, local_wpt):
        self.host = host
        self.git = chromium_git
        self.local_wpt = local_wpt

        self._monorail_api = MonorailAPI
        self.default_port = host.port_factory.get()
        self.finder = PathFinder(host.filesystem)
        self.owners_extractor = DirectoryOwnersExtractor(host.filesystem)
        self.new_failures_by_directory = defaultdict(list)

    def main(self, wpt_revision_start, wpt_revision_end, rebaselined_tests, test_expectations, issue, patchset,
             dry_run=True, service_account_key_json=None):
        """Files bug reports for new failures.

        Args:
            wpt_revision_start: The start of the imported WPT revision range
                (exclusive), i.e. the last imported revision.
            wpt_revision_end: The end of the imported WPT revision range
                (inclusive), i.e. the current imported revision.
            rebaselined_tests: A list of test names that have been rebaselined.
            test_expectations: A dictionary mapping names of tests that cannot
                be rebaselined to a list of new test expectation lines.
            issue: The issue number of the import CL (a string).
            patchset: The patchset number of the import CL (a string).
            dry_run: If True, no bugs will be actually filed to crbug.com.
            service_account_key_json: The path to a JSON private key of a
                service account for accessing Monorail. If None, try to get an
                access token from luci-auth.

        Note: "test names" are paths of the tests relative to LayoutTests.
        """
        gerrit_url = SHORT_GERRIT_PREFIX + issue
        gerrit_url_with_ps = gerrit_url + '/' + patchset + '/'

        changed_test_baselines = self.find_changed_baselines_of_tests(rebaselined_tests)
        self.examine_baseline_changes(changed_test_baselines, gerrit_url_with_ps)
        self.examine_new_test_expectations(test_expectations)

        bugs = self.create_bugs_from_new_failures(wpt_revision_start, wpt_revision_end, gerrit_url)
        self.file_bugs(bugs, dry_run, service_account_key_json)

    def find_changed_baselines_of_tests(self, rebaselined_tests):
        """Finds the corresponding changed baselines of each test.

        Args:
            rebaselined_tests: A list of test names that have been rebaselined.

        Returns:
            A dictionary mapping test names to paths of their baselines changed
            in this import CL (paths relative to the root of Chromium repo).
        """
        test_baselines = {}
        changed_files = self.git.changed_files()
        for test_name in rebaselined_tests:
            test_without_ext, _ = self.host.filesystem.splitext(test_name)
            changed_baselines = []
            # TODO(robertma): Refactor this into layout_tests.port.base.
            baseline_name = test_without_ext + '-expected.txt'
            for changed_file in changed_files:
                if changed_file.endswith(baseline_name):
                    changed_baselines.append(changed_file)
            if changed_baselines:
                test_baselines[test_name] = changed_baselines
        return test_baselines

    def examine_baseline_changes(self, changed_test_baselines, gerrit_url_with_ps):
        """Examines all changed baselines to find new failures.

        Args:
            changed_test_baselines: A dictionary mapping test names to paths of
                changed baselines.
            gerrit_url_with_ps: Gerrit URL of this CL with the patchset number.
        """
        for test_name, changed_baselines in changed_test_baselines.iteritems():
            directory = self.find_owned_directory(test_name)
            if not directory:
                _log.warning('Cannot find OWNERS of %s', test_name)
                continue

            for baseline in changed_baselines:
                if self.more_failures_in_baseline(baseline):
                    self.new_failures_by_directory[directory].append(
                        TestFailure(TestFailure.BASELINE_CHANGE, test_name,
                                    baseline_path=baseline, gerrit_url_with_ps=gerrit_url_with_ps)
                    )

    def more_failures_in_baseline(self, baseline):
        diff = self.git.run(['diff', '-U0', 'origin/master', '--', baseline])
        delta_failures = 0
        for line in diff.splitlines():
            if line.startswith('+FAIL'):
                delta_failures += 1
            if line.startswith('-FAIL'):
                delta_failures -= 1
        return delta_failures > 0

    def examine_new_test_expectations(self, test_expectations):
        """Examines new test expectations to find new failures.

        Args:
            test_expectations: A dictionary mapping names of tests that cannot
                be rebaselined to a list of new test expectation lines.
        """
        for test_name, expectation_lines in test_expectations.iteritems():
            directory = self.find_owned_directory(test_name)
            if not directory:
                _log.warning('Cannot find OWNERS of %s', test_name)
                continue

            for expectation_line in expectation_lines:
                self.new_failures_by_directory[directory].append(
                    TestFailure(TestFailure.NEW_EXPECTATION, test_name,
                                expectation_line=expectation_line)
                )

    def create_bugs_from_new_failures(self, wpt_revision_start, wpt_revision_end, gerrit_url):
        """Files bug reports for new failures.

        Args:
            wpt_revision_start: The start of the imported WPT revision range
                (exclusive), i.e. the last imported revision.
            wpt_revision_end: The end of the imported WPT revision range
                (inclusive), i.e. the current imported revision.
            gerrit_url: Gerrit URL of the CL.

        Return:
            A list of MonorailIssue objects that should be filed.
        """
        imported_commits = self.local_wpt.commits_in_range(wpt_revision_start, wpt_revision_end)
        bugs = []
        for directory, failures in self.new_failures_by_directory.iteritems():
            summary = '[WPT] New failures introduced in {} by import {}'.format(directory, gerrit_url)

            full_directory = self.host.filesystem.join(self.finder.layout_tests_dir(), directory)
            owners_file = self.host.filesystem.join(full_directory, 'OWNERS')
            is_wpt_notify_enabled = self.owners_extractor.is_wpt_notify_enabled(owners_file)

            owners = self.owners_extractor.extract_owners(owners_file)
            # owners may be empty but not None.
            cc = owners + ['robertma@chromium.org']

            component = self.owners_extractor.extract_component(owners_file)
            # component could be None.
            components = [component] if component else None

            prologue = ('WPT import {} introduced new failures in {}:\n\n'
                        'List of new failures:\n'.format(gerrit_url, directory))
            failure_list = ''
            for failure in failures:
                failure_list += str(failure) + '\n'

            epilogue = '\nThis import contains upstream changes from {} to {}:\n'.format(
                wpt_revision_start, wpt_revision_end
            )
            commit_list = self.format_commit_list(imported_commits, full_directory)

            description = prologue + failure_list + epilogue + commit_list

            bug = MonorailIssue.new_chromium_issue(summary, description, cc, components)
            _log.info(unicode(bug))

            if is_wpt_notify_enabled:
                _log.info("WPT-NOTIFY enabled in this directory; adding the bug to the pending list.")
                bugs.append(bug)
            else:
                _log.info("WPT-NOTIFY disabled in this directory; discarding the bug.")
        return bugs

    def format_commit_list(self, imported_commits, directory):
        """Formats the list of imported WPT commits.

        Imports affecting the given directory will be highlighted.

        Args:
            imported_commits: A list of (SHA, commit subject) pairs.
            directory: An absolute path of a directory in the Chromium repo, for
                which the list is formatted.

        Returns:
            A multi-line string.
        """
        path_from_wpt = self.host.filesystem.relpath(
            directory, self.finder.path_from_layout_tests('external', 'wpt'))
        commit_list = ''
        for sha, subject in imported_commits:
            # subject is a Unicode string and can contain non-ASCII characters.
            line = u'{}: {}'.format(subject, GITHUB_COMMIT_PREFIX + sha)
            if self.local_wpt.is_commit_affecting_directory(sha, path_from_wpt):
                line += ' [affecting this directory]'
            commit_list += line + '\n'
        return commit_list

    def find_owned_directory(self, test_name):
        """Finds the lowest directory that contains the test and has OWNERS.

        Args:
            The name of the test (a path relative to LayoutTests).

        Returns:
            The path of the found directory relative to LayoutTests.
        """
        # Always use non-virtual test names when looking up OWNERS.
        if self.default_port.lookup_virtual_test_base(test_name):
            test_name = self.default_port.lookup_virtual_test_base(test_name)
        # find_owners_file takes either a relative path from the *root* of the
        # repository, or an absolute path.
        abs_test_path = self.finder.path_from_layout_tests(test_name)
        owners_file = self.owners_extractor.find_owners_file(self.host.filesystem.dirname(abs_test_path))
        if not owners_file:
            return None
        owned_directory = self.host.filesystem.dirname(owners_file)
        short_directory = self.host.filesystem.relpath(owned_directory, self.finder.layout_tests_dir())
        return short_directory

    def file_bugs(self, bugs, dry_run, service_account_key_json=None):
        """Files a list of bugs to Monorail.

        Args:
            bugs: A list of MonorailIssue objects.
            dry_run: A boolean, whether we are in dry run mode.
            service_account_key_json: Optional, see docs for main().
        """
        # TODO(robertma): Better error handling in this method.
        if dry_run:
            _log.info('[dry_run] Would have filed the %d bugs in the pending list.', len(bugs))
            return

        _log.info('Filing %d bugs in the pending list to Monorail', len(bugs))
        api = self._get_monorail_api(service_account_key_json)
        for index, bug in enumerate(bugs, start=1):
            response = api.insert_issue(bug)
            _log.info('[%d] Filed bug: %s', index, MonorailIssue.crbug_link(response['id']))

    def _get_monorail_api(self, service_account_key_json):
        if service_account_key_json:
            return self._monorail_api(service_account_key_json=service_account_key_json)
        token = LuciAuth(self.host).get_access_token()
        return self._monorail_api(access_token=token)


class TestFailure(object):
    """A simple abstraction of a new test failure for the notifier."""

    # Failure types:
    BASELINE_CHANGE = 1
    NEW_EXPECTATION = 2

    def __init__(self, failure_type, test_name, expectation_line='', baseline_path='', gerrit_url_with_ps=''):
        if failure_type == self.BASELINE_CHANGE:
            assert baseline_path and gerrit_url_with_ps
        else:
            assert failure_type == self.NEW_EXPECTATION
            assert expectation_line

        self.failure_type = failure_type
        self.test_name = test_name
        self.expectation_line = expectation_line
        self.baseline_path = baseline_path
        self.gerrit_url_with_ps = gerrit_url_with_ps

    def __str__(self):
        if self.failure_type == self.BASELINE_CHANGE:
            return self._format_baseline_change()
        else:
            return self._format_new_expectation()

    def __eq__(self, other):
        return (
            self.failure_type == other.failure_type and
            self.test_name == other.test_name and
            self.expectation_line == other.expectation_line and
            self.baseline_path == other.baseline_path and
            self.gerrit_url_with_ps == other.gerrit_url_with_ps
        )

    def _format_baseline_change(self):
        assert self.failure_type == self.BASELINE_CHANGE
        result = ''
        # TODO(robertma): Is there any better way than using regexp?
        platform = re.search(r'/platform/([^/]+)/', self.baseline_path)
        if platform:
            result += '[ {} ] '.format(platform.group(1).capitalize())
        result += '{} new failing tests: {}{}'.format(
            self.test_name, self.gerrit_url_with_ps, self.baseline_path)
        return result

    def _format_new_expectation(self):
        assert self.failure_type == self.NEW_EXPECTATION
        # TODO(robertma): Are there saner ways to remove the link to the umbrella bug?
        line = self.expectation_line
        if line.startswith(UMBRELLA_BUG):
            line = line[len(UMBRELLA_BUG):].lstrip()
        return line
