# -*- coding: utf-8 -*-
#
# Copyright (C) 2018-2020 CERN.
# Copyright (C) 2018-2020 RERO.
#
# Invenio-Circulation is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

"""Circulation search API."""

from invenio_search.api import RecordsSearch

from invenio_circulation.errors import MissingRequiredParameterError

from ..proxies import current_circulation


class LoansSearch(RecordsSearch):
    """RecordsSearch for borrowed documents."""

    class Meta:
        """Search only on loans index."""

        index = "loans"
        doc_types = None

    def exclude(self, *args, **kwargs):
        """Add method `exclude` to old elastic search versions."""
        return super().exclude(*args, **kwargs)


def search_by_pid(
    item_pid=None,
    document_pid=None,
    filter_states=None,
    exclude_states=None,
    sort_by_field=None,
    sort_order="asc",
):
    """Retrieve loans attached to the given item or document."""
    search_cls = current_circulation.loan_search_cls
    search = search_cls()

    if document_pid:
        search = search.filter("term", document_pid=document_pid)
    elif item_pid:
        search = search \
            .filter("term", item_pid__value=item_pid["value"]) \
            .filter("term", item_pid__type=item_pid["type"])
    else:
        raise MissingRequiredParameterError(
            description=(
                "One of the parameters 'item_pid' "
                "or 'document_pid' is required."
            )
        )

    if filter_states:
        search = search.filter("terms", state=filter_states)
    elif exclude_states:
        search = search.exclude("terms", state=exclude_states)

    if sort_by_field:
        search = search.sort({sort_by_field: {"order": sort_order}})

    return search


def search_by_patron_item_or_document(
    patron_pid, item_pid=None, document_pid=None, filter_states=None
):
    """Retrieve loans for patron given an item."""
    search_cls = current_circulation.loan_search_cls
    search = search_cls().filter("term", patron_pid=patron_pid)

    if item_pid:
        search = search \
            .filter("term", item_pid__value=item_pid["value"]) \
            .filter("term", item_pid__type=item_pid["type"])
    if document_pid:
        search = search.filter("term", document_pid=document_pid)

    if filter_states:
        search = search.filter("terms", state=filter_states)

    return search


def search_by_patron_pid(patron_pid):
    """Retrieve loans of a patron."""
    search_cls = current_circulation.loan_search_cls
    search = search_cls().filter("term", patron_pid=patron_pid)
    return search
