"""Queryset and manager for the ``Duplicable`` abstract model"""

from django.db import models


class DuplicableQuerySet(models.QuerySet):
    """Queryset for the ``Duplicable`` model."""

    def having_parent_version(self, parent_version):
        """Filter duplicates having a specific parent version.

        Parameters
        ----------
        parent_version: Duplicable
            Instance of a ``Duplicable`` based model for which we want the instances that are
            its direct duplicates

        Returns
        -------
        DuplicableQueryset
            A clone of the original queryset (``self``), filtered.


        Example
        -------

        >>> duplicates = MyDuplicateModel.objects.having_parent_version(instance)

        """

        return self.filter(parent_version=parent_version)

    def having_original_version(self, original_version):
        """Filter duplicates having a specific original version.

        Parameters
        ----------
        original_version: Duplicable
            Instance of a ``Duplicable`` based model for which we want the instances that are
            its duplicates, direct or not.

        Returns
        -------
        DuplicableQueryset
            A clone of the original queryset (``self``), filtered.


        Example
        -------

        >>> duplicates = MyDuplicateModel.objects.having_original_version(instance)

        """

        return self.filter(original_version=original_version)


class DuplicableManager(models.Manager.from_queryset(DuplicableQuerySet)):
    """Default manager for ``Duplicable`` models."""
    pass


# Manage queryset and manager for django-polymorphic, that is old and so cannot
# manage correctly the ``from_queryset`` used to simply create a manager from a QuerySet class
try:
    # Theses imports are just to define some classes if ``django-polymorphic`` is used
    # pylint: disable=wrong-import-position
    from polymorphic.managers import PolymorphicManager, PolymorphicQuerySet
except ImportError:
    # django-polymorphic is not installed so we don't need to manage it
    pass
else:
    class PolymorphicQuerySetForDuplicable(DuplicableQuerySet, PolymorphicQuerySet):
        """A QuerySet to use for models that are polymorphic AND duplicable."""
        pass

    class PolymorphicManagerForDuplicable(
            PolymorphicManager.from_queryset(PolymorphicQuerySetForDuplicable)
        ):
        """A Manager to use for models that are polymorphic AND duplicable."""
        pass
