# Copyright 2011-2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module that contains trybot patch pool code."""

import functools
import logging

from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import gerrit
from chromite.lib import git
from chromite.lib import patch as cros_patch


def ChromiteFilter(patch):
    """Used with FilterFn to isolate patches to chromite."""
    return patch.project == constants.CHROMITE_PROJECT


def ExtManifestFilter(patch):
    """Used with FilterFn to isolate patches to the external manifest."""
    return patch.project == config_lib.GetSiteParams().MANIFEST_PROJECT


def IntManifestFilter(patch):
    """Used with FilterFn to isolate patches to the internal manifest."""
    return patch.project == config_lib.GetSiteParams().MANIFEST_INT_PROJECT


def ManifestFilter(patch):
    """Used with FilterFn to isolate patches to the manifest."""
    return ExtManifestFilter(patch) or IntManifestFilter(patch)


def BranchFilter(branch, patch):
    """Used with FilterFn to isolate patches based on a specific upstream."""
    return patch.tracking_branch == branch


class TrybotPatchPool:
    """Represents patches specified by the user to test."""

    def __init__(self, gerrit_patches=(), local_patches=(), remote_patches=()):
        self.gerrit_patches = tuple(gerrit_patches)
        self.local_patches = tuple(local_patches)
        self.remote_patches = tuple(remote_patches)

    def __bool__(self):
        """Returns True if the pool has any patches."""
        return any(
            [self.gerrit_patches, self.local_patches, self.remote_patches]
        )

    # Python 2 glue.
    __nonzero__ = __bool__

    def Filter(self, **kwargs):
        """Returns a new pool with only patches that match constraints.

        Args:
            **kwargs: constraints in the form of attr=value.  I.e.,
                project='chromiumos/chromite', tracking_branch='master'.
        """

        def AttributeFilter(patch):
            # TODO(b/236161656): Fix.
            # pylint: disable-next=consider-using-dict-items
            for key in kwargs:
                if getattr(patch, key, object()) != kwargs[key]:
                    return False
            return True

        return self.FilterFn(AttributeFilter)

    def FilterFn(self, filter_fn, negate=False):
        """Returns a new pool with only patches that match constraints.

        Args:
            filter_fn: Functor that accepts a 'patch' argument, and returns
                whether to include the patch in the results.
            negate: Return patches that don't pass the filter_fn.
        """
        f = filter_fn
        if negate:
            f = lambda p: not filter_fn(p)

        return self.__class__(
            gerrit_patches=(x for x in self.gerrit_patches if f(x)),
            local_patches=(x for x in self.local_patches if f(x)),
            remote_patches=(x for x in self.remote_patches if f(x)),
        )

    def FilterManifest(self, negate=False):
        """Return a patch pool with only patches to the manifest."""
        return self.FilterFn(ManifestFilter, negate=negate)

    def FilterIntManifest(self, negate=False):
        """Return a patch pool with only patches to the internal manifest."""
        return self.FilterFn(IntManifestFilter, negate=negate)

    def FilterExtManifest(self, negate=False):
        """Return a patch pool with only patches to the external manifest."""
        return self.FilterFn(ExtManifestFilter, negate=negate)

    def FilterBranch(self, branch, negate=False):
        """Return a patch pool with only patches from a particular branch."""
        return self.FilterFn(
            functools.partial(BranchFilter, branch), negate=negate
        )

    def __iter__(self):
        for source in [
            self.local_patches,
            self.remote_patches,
            self.gerrit_patches,
        ]:
            for patch in source:
                yield patch

    @classmethod
    def FromOptions(
        cls,
        gerrit_patches=None,
        local_patches=None,
        sourceroot=None,
        remote_patches=None,
    ):
        """Generate patch objects from passed in options.

        Args:
            gerrit_patches: Gerrit ids that gerrit.GetGerritPatchInfo accepts.
            local_patches: Local ids that cros_patch.PrepareLocalPatches
                accepts.
            sourceroot: The source repository to look up |local_patches|.
            remote_patches: Remote ids that cros_patch.PrepareRemotePatches
                accepts.

        Returns:
            A TrybotPatchPool object.

        Raises:
            gerrit.GerritException, cros_patch.PatchException
        """
        if gerrit_patches:
            gerrit_patches = gerrit.GetGerritPatchInfo(gerrit_patches)
            for patch in gerrit_patches:
                if patch.IsAlreadyMerged():
                    logging.warning("Patch %s has already been merged.", patch)
        else:
            gerrit_patches = ()

        if local_patches:
            manifest = git.ManifestCheckout.Cached(sourceroot)
            local_patches = cros_patch.PrepareLocalPatches(
                manifest, local_patches
            )
        else:
            local_patches = ()

        if remote_patches:
            remote_patches = cros_patch.PrepareRemotePatches(remote_patches)
        else:
            remote_patches = ()

        return cls(
            gerrit_patches=gerrit_patches,
            local_patches=local_patches,
            remote_patches=remote_patches,
        )
