"""Perform queries against the cross references (xref) endpoints
"""
from ensembl_rest_client.base import base_rest_client as brc


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class _CrossReferences(object):
    """Perform CrossReferences queries
    """
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_xrefs_symbol(self, species, symbol, db_type=None, external_db=None,
                         object_type=None, norm_func=brc.default_pandas):
        """
        Looks up an external symbol and returns all Ensembl objects linked to
        it. This can be a display name for a gene/transcript/translation, a
        synonym or an externally linked reference. If a gene's transcript is
        linked to the supplied symbol the service will return both gene and
        transcript (it supports transient links). GET method. Queries:
        `xrefs/symbol/:species/:symbol <https://rest.ensembl.org/documentation/info/xref_external>`_.

        Parameters
        ----------
        species : str
            Species name/alias. Example values: 'homo_sapiens human'.
        symbol : str
            Symbol or display name of a gene. Example values: 'BRCA2'.
        db_type : str or NoneType, optional, default: NoneType
            Restrict the search to a database other than the default. Useful if
            you need to use a DB other than core. Example values: 'core
            otherfeatures'.
        external_db : str or NoneType, optional, default: NoneType
            Filter by external database. Example values: 'HGNC'.
        object_type : str or NoneType, optional, default: NoneType
            Filter by feature type. Example values: 'gene'.'transcript'.
        norm_func : obj:`func`, optional, default: default_pandas
            The normalisation function to use when obj.pandas is True

        Returns
        -------
        data : list or dict or :obj:`pandas.DataFrame`
            The rest query data
        """
        method_type = 'GET'
        endpoint = 'xrefs/symbol/{species}/{symbol}'.format(
            species=species,
            symbol=symbol
        )

   
        return self.rest_query(
                method_type,
                endpoint,
                db_type=db_type,
                external_db=external_db,
                object_type=object_type,
                norm_func=norm_func
            )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_xrefs_id(self, query_id, all_levels=None, db_type=None,
                     external_db=None, object_type=None, species=None,
                     norm_func=brc.default_pandas):
        """
        Perform lookups of Ensembl Identifiers and retrieve their external
        references in other databases. GET method. Queries:
        `xrefs/id/:id <https://rest.ensembl.org/documentation/info/xref_id>`_.

        Parameters
        ----------
        query_id : str
            An Ensembl Stable ID. Example values: 'ENSG00000157764'.
        all_levels : bool or NoneType, optional, default: NoneType
            Set to find all genetic features linked to the stable ID, and fetch
            all external references for them. Specifying this on a gene will
            also return values from its transcripts and translations. Example
            values: '1'.
        db_type : str or NoneType, optional, default: NoneType
            Restrict the search to a database other than the default. Useful if
            you need to use a DB other than core. Example values: 'core
            otherfeatures'.
        external_db : str or NoneType, optional, default: NoneType
            Filter by external database. Example values: 'HGNC'.
        object_type : str or NoneType, optional, default: NoneType
            Filter by feature type. Example values: 'gene transcript'.
        species : str or NoneType, optional, default: NoneType
            Species name/alias. Example values: 'homo_sapiens human'.
        norm_func : obj:`func`, optional, default: default_pandas
            The normalisation function to use when obj.pandas is True

        Returns
        -------
        data : list or dict or :obj:`pandas.DataFrame`
            The rest query data

        Notes
        -----
        When the external_db is included this seems to return no data. I am not
        sure if this is a fault with this function or the Ensembl REST endpoint
        , I will need to research this.
        """
        method_type = 'GET'
        endpoint = 'xrefs/id/{id}'.format(
            id=query_id
        )

        if external_db is not None:
            all_levels = '1'

        return self.rest_query(
            method_type,
            endpoint,
            all_levels=all_levels,
            db_type=db_type,
            external_db=external_db,
            object_type=object_type,
            species=species,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_xrefs_name(self, name, species, db_type=None, external_db=None,
                       norm_func=brc.default_pandas):
        """
        Performs a lookup based upon the primary accession or display label of
        an external reference and returning the information held by Ensembl
        about the entry. GET method. Queries:
        `xrefs/name/:species/:name <https://rest.ensembl.org/documentation/info/xref_name>`_.

        Parameters
        ----------
        name : str
            Symbol or display name of a gene. Example values: 'BRCA2'.
        species : str
            Species name/alias. Example values: 'homo_sapiens human'.
        db_type : str or NoneType, optional, default: NoneType
            Restrict the search to a database other than the default. Useful if
            you need to use a DB other than core. Example values: 'core
            otherfeatures'.
        external_db : str or NoneType, optional, default: NoneType
            Filter by external database. Example values: 'HGNC'.
        norm_func : obj:`func`, optional, default: default_pandas
            The normalisation function to use when obj.pandas is True

        Returns
        -------
        data : list or dict or :obj:`pandas.DataFrame`
            The rest query data

        
        """
        method_type = 'GET'
        endpoint = 'xrefs/name/{species}/{name}'.format(
            species=species,
            name=name
        )

  
        return self.rest_query(
                method_type,
                endpoint,
                db_type=db_type,
                external_db=external_db,
                norm_func=norm_func
                )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class CrossReferences(brc._BaseRestClient, _CrossReferences):
    """Perform CrossReferences queries
    """
    pass
