# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Find dependencies on pending CLs."""

import re

import attr
from recipe_engine import recipe_api


@attr.s
class Change:
    """Details of a matching change.

    This is meant to match the GerritChange message defined at
    https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/go.chromium.org/luci/buildbucket/proto/common.proto?q=GerritChange
    A few fields have been added for use by this module.
    """

    gerrit_name = attr.ib(type=str)
    change = attr.ib(converter=int)
    project = attr.ib(type=str, default=None)
    patchset = attr.ib(type=int, default=None)
    status = attr.ib(type=str, default=None)
    commit = attr.ib(type=str, default=None)
    parents = attr.ib(type=list, default=attr.Factory(list))

    @property
    def host(self):
        return '{}-review.googlesource.com'.format(self.gerrit_name)

    @property
    def link(self):
        return 'https://{}/{}'.format(self.host, self.change)

    @property
    def name(self):
        return '{}:{}'.format(self.gerrit_name, self.change)

    @property
    def remote(self):
        return 'https://{}.googlesource.com/{}'.format(
            self.gerrit_name, self.project
        )

    @property
    def gerrit_url(self):
        return 'https://{}-review.googlesource.com/c/{}'.format(
            self.gerrit_name, self.change
        )

    def __str__(self):
        return self.name


class CqDepsApi(recipe_api.RecipeApi):
    """Find dependencies on pending CLs."""

    def __init__(self, props, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._details = {}
        self._enabled = not props.disabled
        self._ignore_errors = props.ignore_errors

    def _lookup_cl(self, gerrit_name, commit):
        query_results = self.m.gerrit.change_query(
            'number {}'.format(commit),
            'commit:{}'.format(commit),
            host='{}-review.googlesource.com'.format(gerrit_name),
            max_attempts=2,
            timeout=30,
            # The strange value for _number is to ensure different hashes result
            # in different CL numbers by default. This way we don't accidentally
            # create a cycle by specifying a fixed default value.
            test_data=self.m.json.test_api.output(
                [{'_number': sum(ord(x) for x in commit),}]
            ),
        ).json.output
        if query_results:
            return query_results[0]
        return None

    def resolve(self, gerrit_name, number, statuses=('NEW',)):
        """Recursively resolve dependencies of a CL.

        Resolve dependencies of a CL by parsing its commit message. Looks for
        lines like below, and only in the last "paragraph".

        Requires: gerritname:1, commas-supported:2
        Requires: name:4,spaces-not-required:3
        Requires: name:5,,,,extra-commas-ignored:6,,,,

        Args:
            gerrit_name (str): Name of Gerrit host of initial change.
            number (int|str): Gerrit number or git commit hash of initial
                change.
            statuses (seq(str)): CL statuses to accept.

        Returns a tuple of resolved Change objects (excluding the given change)
        and unresolved Change objects (which are not completely populated).
        This includes dependencies of parent changes with 'NEW' status but not
        the parent changes themselves.
        """

        with self.m.step.nest('resolve CL deps', status='last') as pres:
            if not self._enabled:
                with self.m.step.nest('dependency processing disabled'):
                    return ((), ())

            with self.m.context(infra_steps=True):
                if isinstance(number, str):
                    cl = self._lookup_cl(gerrit_name, number)
                    if not cl:
                        return ((), ())
                    number = cl['_number']

                seen = set()
                deps = {}
                parents = []
                unresolved = []
                initial_change = Change(gerrit_name, number)
                to_process = [initial_change] + initial_change.parents
                # Want all initial details calls to come from this step level so
                # their step names are predictable. Further calls can be made
                # anywhere and will hit the cache.
                _ = self._change_details(initial_change)

                while to_process:
                    current = to_process.pop()
                    deps[current.name] = current
                    seen.add(current.name)

                    parents.extend(current.parents)
                    to_process.extend(
                        x for x in current.parents if x.name not in seen
                    )

                    with self.m.step.nest(
                        'parents {}'.format(current.name)
                    ) as pres:
                        if current.parents:
                            pres.step_summary_text = ', '.join(
                                x.name for x in current.parents
                            )
                        else:
                            pres.step_summary_text = (
                                'all parents already submitted'
                            )

                    for dep in self._resolve(current):
                        if dep.name not in deps:
                            details = self._change_details(dep)
                            if not details:
                                unresolved.append(dep)
                                continue
                            if details['status'] not in statuses:
                                continue

                            if dep.name not in seen:
                                to_process.append(dep)
                            deps[dep.name] = dep

                # If any dependency is a parent of another dependency remove the
                # parent since it's already being accounted for by patching in
                # its child.
                for parent in parents:
                    if parent.name in deps:
                        del deps[parent.name]

                del deps[initial_change.name]

                for dep in deps.values():
                    pres.links[dep.name] = dep.link

                # Make sure the last step passes because _change_details might
                # fail for an individual CL in ways we don't care about.
                with self.m.step.nest('pass'):
                    pass

                return deps.values(), unresolved

    def _parse_commit_message(self, change):
        """Convert a commit message into a dependency list.

        For example,

            Requires: gerritname:1, commas-supported:2
            Requires: name:4,spaces-not-required:3
            Requires: 5,,,,extra-commas-ignored:6,,,,

        becomes

            [
                Change("gerritname", 1),
                Change("commas-supported", 2),
                Change("spaces-not-required", 3),
                Change("name", 4),
                Change(change.gerrit_name, 5),
                Change("extra-commas-ignored", 6),
            ]
        """

        details = self._change_details(change)
        current_revision = details['revisions'][details['current_revision']]
        commit_message = current_revision['commit']['message']
        last_paragraph = commit_message.split('\n\n')[-1]

        for line in last_paragraph.split('\n'):
            if ':' not in line:
                continue
            name, value = line.split(':', 1)

            if name != 'Requires':
                continue

            values = value.split(',')
            for val in values:
                val = val.strip()
                if not val:
                    continue

                gerrit_name = change.gerrit_name
                if ':' in val:
                    gerrit_name, number = val.split(':')
                else:
                    number = val

                if not number.isdigit():
                    if self._ignore_errors:
                        continue

                    else:
                        with self.m.step.nest('invalid requirement') as pres:
                            pres.step_summary_text = (
                                'Format is "<gerrit-host>:<cl-number>" or '
                                '"<cl-number>", {!r} does not match'.format(val)
                            )
                            pres.status = 'FAILURE'
                        raise self.m.step.StepFailure('invalid requirement')

                yield Change(gerrit_name, number)

    def _resolve(self, change):
        """Resolve dependencies of the given change.

        Retrieve and parse the commit message of the given change, extracting
        from "Requires:" lines (see resolve function above for details). Does
        not attempt to verify if these dependent changes are accessible or
        even valid.

        Args:
            change (Change): Change to resolve dependencies for.

        Returns a list of changes on which the given change depends. This
        includes dependencies of parent changes with 'NEW' status but not the
        parent changes themselves.
        """

        with self.m.step.nest('resolve deps for {}'.format(change)) as pres:
            deps = []
            for dep in self._parse_commit_message(change):
                deps.append(dep)
                pres.links[dep.name] = dep.link
            if not deps:
                pres.step_summary_text = 'no dependencies'
            return deps

    def _change_details(self, change, _kw_only=(), test_status='NEW'):
        assert not _kw_only
        if change.name in self._details:
            return self._details[change.name]

        try:
            step = self.m.gerrit.change_details(
                'details {}'.format(change),
                change_id=str(change.change),
                host=change.host,
                query_params=['CURRENT_COMMIT', 'CURRENT_REVISION',],
                max_attempts=2,
                timeout=30,
                test_data=self.m.json.test_api.output(
                    {
                        'current_revision': 'HASH',
                        'revisions': {
                            'HASH': {
                                '_number': 1,
                                'commit': {
                                    'message': '',
                                    'parents': [{'commit': 'PARENT',}],
                                },
                            }
                        },
                        'project': 'project',
                        'status': test_status,
                    }
                ),
            )
            details = step.json.output

        except self.m.step.StepFailure:
            details = {}

        self._details[change.name] = details
        if details:
            change.project = details['project']
            current_revision = details['revisions'][details['current_revision']]
            change.patchset = current_revision['_number']
            change.status = details['status']
            change.commit = details['current_revision']

            # If this CL is unsubmitted grab its parent and put it in the
            # cache. We could have several submitted parents in self._details,
            # but that's ok.
            if details['status'] == 'NEW':
                for parent in current_revision['commit']['parents']:
                    parent_result = self._lookup_cl(
                        change.gerrit_name, parent['commit'],
                    )
                    # There could be no parent CL because this is the first
                    # commit or because the parent was submitted without going
                    # through Gerrit.
                    if not parent_result:
                        continue

                    parent_change = Change(
                        gerrit_name=change.gerrit_name,
                        change=parent_result['_number'],
                    )
                    self._change_details(parent_change, test_status='SUBMITTED')
                    if parent_change.status == 'NEW':
                        if parent_change.commit != parent['commit']:
                            raise self.m.step.StepFailure(
                                '{} has parent {} which is not the current '
                                'revision of its parent, {} ({})'.format(
                                    change.name,
                                    parent['commit'],
                                    parent_change.name,
                                    parent_change.commit,
                                )
                            )

                        change.parents.append(parent_change)

        return self._details[change.name]
