class ReferentMethods(object):
    """Referent methods of the public API."""

    def referent(self, referent_ids, text_format=None):
        """Gets data of one or more referents.

        This method can get multiple referents in one call,
        thus increasing performance.

        Args:
            referent_ids (:obj:`list`): A list of referent IDs.
            text_format (:obj:`str`, optional): Text format of the results
                ('dom', 'html', 'markdown' or 'plain').

        Returns:
            :obj:`dict`

        Note:
            Using this method you can get the referent itself instead of
            the referents of a song or webpage which is what
            :meth:`referents() <PublicAPI.referents>` gets.

        """
        params = {"text_format": text_format or self.response_format}
        if len(referent_ids) == 1:
            endpoint = "referents/{}".format(referent_ids[0])
        else:
            endpoint = "referents/multi"
            params = [("text_format", params["text_format"])]
            for id in referent_ids:
                params.append(("ids[]", id))

        return self._make_request(path=endpoint, params_=params, public_api=True)

    def referents(
        self,
        song_id=None,
        web_page_id=None,
        created_by_id=None,
        per_page=None,
        page=None,
        text_format=None,
    ):
        """Gets item's referents

        You must supply :obj:`song_id`, :obj:`web_page_id`, or :obj:`created_by_id`.

        Args:
            song_id (:obj:`int`, optional): song ID
            web_page_id (:obj:`int`, optional): web page ID
            created_by_id (:obj:`int`, optional): User ID of the contributer
                who created the annotation(s).
            per_page (:obj:`int`, optional): Number of results to
                return per page. It can't be more than 50.
            text_format (:obj:`str`, optional): Text format of the results
                ('dom', 'html', 'markdown' or 'plain').

        Returns:
            :obj:`dict`

        """
        msg = "Must supply `song_id`, `web_page_id`, or `created_by_id`."
        assert any([song_id, web_page_id, created_by_id]), msg
        msg = "Pass only one of `song_id` and `web_page_id`, not both."
        assert bool(song_id) ^ bool(web_page_id), msg

        endpoint = "referents"
        params = {
            "song_id": song_id,
            "web_page_id": web_page_id,
            "created_by_id": created_by_id,
            "per_page": per_page,
            "page": page,
            "text_format": text_format or self.response_format,
        }
        return self._make_request(endpoint, params_=params, public_api=True)

    def referents_charts(
        self,
        time_period="day",
        chart_genre="all",
        per_page=None,
        page=None,
        text_format=None,
    ):
        """Gets the referents (lyrics) charts.

        Alias for :meth:`charts() <PublicAPI.charts>`.

        Args:
            time_period (:obj:`str`, optional): Time period of the results
                ('day', 'week', 'month' or 'all_time').
            chart_genre (:obj:`str`, optional): The genre of the results.
            per_page (:obj:`int`, optional): Number of results to
                return per request. It can't be more than 50.
            page (:obj:`int`, optional): Paginated offset (number of the page).
            text_format (:obj:`str`, optional): Text format of the results
                ('dom', 'html', 'markdown' or 'plain').

        Returns:
            :obj:`dict`

        """
        return self.charts(
            time_period=time_period,
            chart_genre=chart_genre,
            per_page=per_page,
            page=page,
            text_format=text_format,
            type_="referents",
        )
