"""Perform queries against the information endpoints
"""
from ensembl_rest_client.base import base_rest_client as brc


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class _Information(object):
    """Perform Information queries
    """
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_analysis(self, species, norm_func=brc.default_pandas):
        """List the names of analyses involved in generating Ensembl data. GET
        method. Queries:
        `info/analysis/:species <https://rest.ensembl.org/documentation/info/analysis>`_.

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens'.
        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 = 'info/analysis/{species}'.format(
            species=species
        )

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_assembly(self, species, bands=None, synonyms=None,
                          norm_func=brc.default_pandas):
        """List the currently available assemblies for a species, along with
        toplevel sequences, chromosomes and cytogenetic bands. GET method.
        Queries:
        `info/assembly/:species <https://rest.ensembl.org/documentation/info/assembly_info>`_.

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens human'.
        bands : `bool` or `NoneType`, optional, default: `NoneType`
            If set to `True`, include karyotype band information. Only display
            if band information is available.
        synonyms : `bool` or `NoneType`, optional, default: `NoneType`
            If set to `True`, include information about known synonyms.
        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 = 'info/assembly/{species}'.format(
            species=species
        )

        return self.rest_query(
            method_type,
            endpoint,
            bands=bands,
            synonyms=synonyms,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_region_assembly(self, region_name, species, bands=None,
                                 synonyms=None,  norm_func=brc.default_pandas):
        """Returns information about the specified toplevel sequence region for
        the given species. GET method. Queries:
        `info/assembly/:species/:region_name <https://rest.ensembl.org/documentation/info/assembly_stats>`_.

        Parameters
        ----------
        region_name : `str`
            The (top level) sequence region name. Example values: 'X'.
        species : `str`
            Species name/alias. Example values: 'homo_sapiens human'.
        bands : `bool` or `NoneType`, optional, default: `NoneType`
            If set to `True`, include karyotype band information. Only display
            if band information is available.
        synonyms : `bool` or `NoneType`, optional, default: `NoneType`
            If set to `True`, include information about known synonyms.
        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 = 'info/assembly/{species}/{region_name}'.format(
            species=species,
            region_name=region_name
        )

        return self.rest_query(
            method_type,
            endpoint,
            bands=bands,
            synonyms=synonyms,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_biotypes(self, species, norm_func=brc.default_pandas):
        """List the functional classifications of gene models that Ensembl
        associates with a particular species. Useful for restricting the type
        of genes/transcripts retrieved by other endpoints. GET method. Queries:
        `info/biotypes/:species <https://rest.ensembl.org/documentation/info/biotypes>`_.

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens'.
        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 = 'info/biotypes/{species}'.format(
            species=species
        )

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_biotypes_groups(self, group=None, object_type=None,
                                 norm_func=brc.default_pandas):
        """Without argument the list of available biotype groups is returned. With
        :group argument provided, list the properties of biotypes within that
        group. Object type (gene or transcript) can be provided for filtering.
        GET method. Queries:
        `info/biotypes/groups/:group/:object_type <https://rest.ensembl.org/documentation/info/biotypes_groups>`_.

        Parameters
        ----------
        group : `str`, optional, default: `NoneType`
            Biotype group. Example values: 'coding'.
        object_type : `str`, optional, default: `NoneType`
            Object type (gene or transcript). Example values: 'gene'.
        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 = 'info/biotypes/groups'

        # These are optional but are encoded in the URL endpoint directly
        # I think this differs from other optional arguments
        # TODO: I need a generic solution to this
        if group is not None:
            endpoint = '/{endpoint}/{group}'.format(
                endpoint=endpoint,
                group=group
            )

            if object_type is not None:
                endpoint = '/{endpoint}/{object_type}'.format(
                    endpoint=endpoint,
                    object_type=object_type
                )

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_biotypes_name(self, name, object_type=None,
                               norm_func=brc.default_pandas):
        """List the properties of biotypes with a given name. Object type (gene
        or transcript) can be provided for filtering. GET method. Queries:
        `info/biotypes/name/:name/:object_type <https://rest.ensembl.org/documentation/info/biotypes_name>`_

        Parameters
        ----------
        name : `str`
            Biotype name. Example values: 'protein_coding'.
        object_type : `str`, optional, default: `NoneType`
            Object type (gene or transcript). Example values: 'gene'.
        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 = 'info/biotypes/name/{name}'.format(
            name=name
        )

        # These are optional but are encoded in the URL endpoint directly
        # I think this differs from other optional arguments
        # TODO: I need a generic solution to this
        if object_type is not None:
            endpoint = '/{endpoint}/{object_type}'.format(
                endpoint=endpoint,
                object_type=object_type
            )

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_compara_methods(self, class_method=None, compara=None,
                                 norm_func=brc.default_pandas):
        """List all compara analyses available (an analysis defines the type of
        comparative data). GET method. Queries:
        `info/compara/methods <https://rest.ensembl.org/documentation/info/compara_methods>`_

        Parameters
        ----------
        class_method : `str` or `NoneType`, optional, default: `NoneType`
            The class of the method to query for. Regular expression patterns
            are supported. Example values: 'GenomicAlign'.
        compara : `str` or `NoneType`, optional, default: `NoneType`
            Name of the compara database to use. Multiple comparas exist on a
            server for separate species divisions. Example values:
            'vertebrates'.
        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 = 'info/compara/methods'

        kwargs = {
            'class': class_method,
            'compara': compara
        }
        return self.rest_query(
            method_type,
            endpoint,
            norm_func=norm_func,
            **kwargs
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_compara_species_sets(self, method, compara=None,
                                      norm_func=brc.default_pandas):
        """List all collections of species analysed with the specified compara
        method. GET method. Queries:
        `info/compara/species_sets/:method <https://rest.ensembl.org/documentation/info/compara_species_sets>`_

        Parameters
        ----------
        method : `str`
            Filter by compara method. Use one the methods returned by
            /info/compara/methods endpoint. Example values: 'EPO'.
        compara : `str` or `NoneType`, optional, default: `NoneType`
            Name of the compara database to use. Multiple comparas exist on a
            server for separate species divisions. Example values:
            'vertebrates'.
        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 = 'info/compara/species_sets/{method}'.format(
            method=method
        )

        return self.rest_query(
            method_type,
            endpoint,
            compara=compara,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_comparas(self, norm_func=brc.default_pandas):
        """Lists all available comparative genomics databases and their data
        release. DEPRECATED: use info/genomes/division instead. GET method.
        Queries:
        `info/comparas <https://rest.ensembl.org/documentation/info/comparas>`_

        Parameters
        ----------
        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 = 'info/comparas'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_data(self, norm_func=brc.default_pandas):
        """Shows the data releases available on this REST server. May return more
        than one release (unfrequent non-standard Ensembl configuration). GET
        method. Queries:
        `info/data <https://rest.ensembl.org/documentation/info/data>`_

        Parameters
        ----------
        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 = 'info/data'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_eg_version(self, norm_func=brc.default_pandas):
        """Returns the Ensembl Genomes version of the databases backing this
        service. GET method. Queries:
        `info/eg_version <https://rest.ensembl.org/documentation/info/eg_version>`_

        Parameters
        ----------
        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 = 'info/eg_version'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_external_dbs(self, species, feature=None, query_filter=None,
                              norm_func=brc.default_pandas):
        """Lists all available external sources for a species. GET method. Queries:
        `info/external_dbs/:species <https://rest.ensembl.org/documentation/info/external_dbs>`_

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens'.
        feature : `str` or `NoneType`, optional, default: `NoneType`
            Only return external DB entries for a given feature. Example
            values: 'xref dna_align_feature'. Allowed values: dna_align_feature
            protein_align_feature unmapped_object xref seq_region_synonym
        query_filter : `str` or `NoneType`, optional, default: `NoneType`
            Restrict external DB searches to a single source or pattern. SQL-
            LIKE patterns are supported. Example values: 'HGNC GO%'.
        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 = 'info/external_dbs/{species}'.format(
            species=species
        )

        return self.rest_query(
            method_type,
            endpoint,
            feature=feature,
            filter=query_filter,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_divisions(self, norm_func=brc.default_pandas):
        """Get list of all Ensembl divisions for which information is available.
        GET method. Queries:
        `info/divisions <https://rest.ensembl.org/documentation/info/info_divisions>`_

        Parameters
        ----------
        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 = 'info/divisions'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_genomes(self, genome_name, expand=None,
                         norm_func=brc.default_pandas):
        """Find information about a given genome. GET method. Queries:
        `info/genomes/:genome_name <https://rest.ensembl.org/documentation/info/info_genome>`_

        Parameters
        ----------
        genome_name : `str`
            The production name of the genome. Example values:
            'nanoarchaeum_equitans_kin4_m'.
        expand : `bool` or `NoneType`, optional, default: `NoneType`
            Expands the information to include details of sequences. Can be
            very large.
        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 = 'info/genomes/{genome_name}'.format(
            genome_name=genome_name
        )

        return self.rest_query(
            method_type,
            endpoint,
            expand=expand,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_genomes_accession(self, accession, expand=None,
                                   norm_func=brc.default_pandas):
        """Find information about genomes containing a specified INSDC accession.
        GET method. Queries:
        `info/genomes/accession/:accession <https://rest.ensembl.org/documentation/info/info_genomes_accession>`_

        Parameters
        ----------
        accession : `str`
            INSDC sequence accession (optionally versioned). Example values:
            'U00096'.
        expand : `bool` or `NoneType`, optional, default: `NoneType`
            Expands the information to include details of sequences. Can be
            very large.
        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 = 'info/genomes/accession/{accession}'.format(
            accession=accession
        )

        return self.rest_query(
            method_type,
            endpoint,
            expand=expand,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_genomes_assembly(self, assembly_id, expand=None,
                                  norm_func=brc.default_pandas):
        """Find information about a genome with a specified assembly. GET method.
        Queries:
        `info/genomes/assembly/:assembly_id <https://rest.ensembl.org/documentation/info/info_genomes_assembly>`_

        Parameters
        ----------
        assembly_id : `str`
            INSDC assembly ID (optionally versioned). Example values:
            'GCA_000005005.6'.
        expand : `bool` or `NoneType`, optional, default: `NoneType`
            Expands the information to include details of sequences. Can be
            very large.
        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 = 'info/genomes/assembly/{assembly_id}'.format(
            assembly_id=assembly_id
        )

        return self.rest_query(
            method_type,
            endpoint,
            expand=expand,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_genomes_division(self, division, expand=None,
                                  norm_func=brc.default_pandas):
        """Find information about all genomes in a given division. May be large
        for Ensembl Bacteria. GET method. Queries:
        `info/genomes/division/:division_name <https://rest.ensembl.org/documentation/info/info_genomes_division>`_

        Parameters
        ----------
        division : `str`
            The name of the division. Example values: 'EnsemblPlants'.
        expand : `bool` or `NoneType`, optional, default: `NoneType`
            Expands the information to include details of sequences. Can be
            very large.
        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 = 'info/genomes/division/{division}'.format(
            division=division
        )

        return self.rest_query(
            method_type,
            endpoint,
            expand=expand,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_genomes_taxonomy(self, taxon_name, expand=None,
                                  norm_func=brc.default_pandas):
        """Find information about all genomes beneath a given node of the
        taxonomy. GET method. Queries:
        `info/genomes/taxonomy/:taxon_name <https://rest.ensembl.org/documentation/info/info_genomes_taxonomy>`_

        Parameters
        ----------
        taxon_name : `str`
            Taxon name or NCBI taxonomy ID. Example values: 'Homo sapiens'.
        expand : `bool` or `NoneType`, optional, default: `NoneType`
            Expands the information to include details of sequences. Can be
            very large.
        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 = 'info/genomes/taxonomy/{taxon_name}'.format(
            taxon_name=taxon_name
        )

        return self.rest_query(
            method_type,
            endpoint,
            expand=expand,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_ping(self, norm_func=brc.default_pandas):
        """Checks if the service is alive. GET method. Queries:
        `info/ping <https://rest.ensembl.org/documentation/info/ping>`_

        Parameters
        ----------
        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 = 'info/ping'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_rest(self, norm_func=brc.default_pandas):
        """Shows the current version of the Ensembl REST API. GET method. Queries:
        `info/rest <https://rest.ensembl.org/documentation/info/rest>`_

        Parameters
        ----------
        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 = 'info/rest'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_software(self, norm_func=brc.default_pandas):
        """Shows the current version of the Ensembl API used by the REST server.
        GET method. Queries:
        `info/software <https://rest.ensembl.org/documentation/info/software>`_

        Parameters
        ----------
        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 = 'info/software'

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_species(self, division=None, hide_strain_info=None,
                         strain_collection=None, norm_func=brc.default_pandas):
        """Lists all available species, their aliases, available adaptor groups
        and data release. GET method. Queries:
        `info/species <https://rest.ensembl.org/documentation/info/species>`_

        Parameters
        ----------
        division : `str` or `NoneType`, optional, default: `NoneType`
            Filter by Ensembl or Ensembl Genomes division. Example values:
            'EnsemblVertebrates'.
        hide_strain_info : `bool` or `NoneType`, optional, default: `NoneType`
            Show/hide strain and strain_collection info in the output.
        strain_collection : `str` or `NoneType`, optional, default: `NoneType`
            Filter by strain_collection. Example values: 'mouse'.
        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 = 'info/species'

        return self.rest_query(
            method_type,
            endpoint,
            division=division,
            hide_strain_info=hide_strain_info,
            strain_collection=strain_collection,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_variation(self, species, query_filter=None,
                           norm_func=brc.default_pandas):
        """List the variation sources used in Ensembl for a species. GET method.
        Queries:
        `info/variation/:species <https://rest.ensembl.org/documentation/info/variation>`_

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens'.
        query_filter : `str` or `NoneType`, optional, default: `NoneType`
            Restrict the variation source searches to a single source. Example
            values: 'dbSNP ClinVar OMIM UniProt HGMD'.
        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 = 'info/variation/{species}'.format(
            species=species
        )

        return self.rest_query(
            method_type,
            endpoint,
            filter=query_filter,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_variation_consequence_types(self, rank=None,
                                             norm_func=brc.default_pandas):
        """Lists all variant consequence types. GET method. Queries:
        `info/variation/consequence_types <https://rest.ensembl.org/documentation/info/variation_consequence_types>`_

        Parameters
        ----------
        rank : `bool` or `NoneType`, optional, default: `NoneType`
            Include consequence ranking.
        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 = 'info/variation/consequence_types'

        return self.rest_query(
            method_type,
            endpoint,
            rank=rank,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_variation_individuals(self, population_name, species,
                                       norm_func=brc.default_pandas):
        """List all individuals for a population from a species. GET method.
        Queries:
        `info/variation/populations/:species:/:population_name <https://rest.ensembl.org/documentation/info/variation_population_name>`_

        Parameters
        ----------
        population_name : `str`
            Population name. Example values: '1000GENOMES:phase_3:ASW'.
        species : `str`
            Species name/alias. Example values: '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
        """
        method_type = 'GET'
        endpoint = (
            'info/variation/populations/{species}/{population_name}'.format(
                species=species,
                population_name=population_name
            )
        )

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

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_info_variation_populations(self, species, query_filter=None,
                                       norm_func=brc.default_pandas):
        """List all populations for a species. GET method. Queries:
        `info/variation/populations/:species <https://rest.ensembl.org/documentation/info/variation_populations>`_

        Parameters
        ----------
        species : `str`
            Species name/alias. Example values: 'homo_sapiens'.
        query_filter : `str` or `NoneType`, optional, default: `NoneType`
            Restrict populations returned to e.g. only populations with LD
            data. It is highly recommended to set a filter and to avoid loading
            the complete list of populations. Example values: 'LD'.
        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 = 'info/variation/populations/{species}'.format(
            species=species
        )

        return self.rest_query(
            method_type,
            endpoint,
            filter=query_filter,
            norm_func=norm_func
        )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class Information(brc._BaseRestClient, _Information):
    """Perform Information queries
    """
    pass
