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


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class _Sequence(object):
    """Perform Sequence queries
    """
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_sequence_id(self, query_id, db_type=None, end=None,
                        expand_3prime=None, expand_5prime=None,
                        data_format=None, mask=None, mask_feature=None,
                        multiple_sequences=None, object_type=None,
                        species=None, start=None, data_type=None,
                        norm_func=brc.default_pandas):
        """
        Request multiple types of sequence by stable identifier. Supports
        feature masking and expand options. GET method. Queries:
        `sequence/id/:id <https://rest.ensembl.org/documentation/info/sequence_id>`_.
        Max slice length: 1e7.

        Parameters
        ----------
        query_id : str
            An Ensembl stable ID. Example values: 'ENSG00000157764
            ENSG00000157764.fasta (supported on some deployments)'.
        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'.
        end : int or NoneType, optional, default: NoneType
            Trim the end of the sequence by this many basepairs. Trimming is
            relative to reading direction and in the coordinate system of the
            stable identifier. Parameter can not be used in conjunction with
            expand_5prime or expand_3prime. Example values: '1000'.
        expand_3prime : int or NoneType, optional, default: NoneType
            Expand the sequence downstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        expand_5prime : int or NoneType, optional, default: NoneType
            Expand the sequence upstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        data_format : str or NoneType, optional, default: NoneType
            Format of the data. Example values: 'fasta'. Allowed values: fasta
        mask : str or NoneType, optional, default: NoneType
            Request the sequence masked for repeat sequences. Hard will mask
            all repeats as N's and soft will mask repeats as lowercased
            characters. Only available when using genomic sequence type.
            Example values: 'hard'. Allowed values: hard,soft
        mask_feature : bool or NoneType, optional, default: NoneType
            Mask features on the sequence. If sequence is genomic, mask
            introns. If sequence is cDNA, mask UTRs. Incompatible with the
            'mask' option.
        multiple_sequences : bool or NoneType, optional, default: NoneType
            Allow the service to return more than 1 sequence per identifier.
            This is useful when querying for a gene but using a type such as
            protein.
        object_type : str or NoneType, optional, default: NoneType
            Filter by feature type. Example values: 'gene'.
        species : str or NoneType, optional, default: NoneType
            Species name/alias. Example values: 'homo_sapiens'.
        start : int or NoneType, optional, default: NoneType
            Trim the start of the sequence by this many basepairs. Trimming is
            relative to reading direction and in the coordinate system of the
            stable identifier. Parameter can not be used in conjunction with
            expand_5prime or expand_3prime. Example values: '1000'.
        data_type : str or NoneType, optional, default: NoneType
            Type of sequence. Defaults to genomic where applicable, i.e. not
            translations. cdna refers to the spliced transcript sequence with
            UTR; cds refers to the spliced transcript sequence without UTR.
            Example values: 'cds'. Allowed values: genomic,cds,cdna,protein
        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'
        slice_length = 1e7
        endpoint = 'sequence/id/{id}'.format(
            id=query_id
        )

        return self.rest_query(
            method_type,
            endpoint,
            slice_length=slice_length,
            db_type=db_type,
            end=end,
            expand_3prime=expand_3prime,
            expand_5prime=expand_5prime,
            format=data_format,
            mask=mask,
            mask_feature=mask_feature,
            multiple_sequences=multiple_sequences,
            object_type=object_type,
            species=species,
            start=start,
            type=data_type,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def post_sequence_id(self, ids, db_type=None, end=None,
                         expand_3prime=None, expand_5prime=None,
                         data_format=None, mask=None, mask_feature=None,
                         object_type=None, species=None, start=None,
                         data_type=None, norm_func=brc.default_pandas):
        """
        Request multiple types of sequence by a stable identifier list. POST
        method. Queries:
        `sequence/id <https://rest.ensembl.org/documentation/info/sequence_id_post>`_.
        Max post size: 50. Max slice length: 1e7.

        Parameters
        ----------
        ids : list
            Post option not defined in required/optional args.
        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'.
        end : int or NoneType, optional, default: NoneType
            Trim the end of the sequence by this many basepairs. Trimming is
            relative to reading direction and in the coordinate system of the
            stable identifier. Parameter can not be used in conjunction with
            expand_5prime or expand_3prime. Example values: '1000'.
        expand_3prime : int or NoneType, optional, default: NoneType
            Expand the sequence downstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        expand_5prime : int or NoneType, optional, default: NoneType
            Expand the sequence upstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        data_format : str or NoneType, optional, default: NoneType
            Format of the data. Example values: 'fasta'. Allowed values: fasta
        mask : str or NoneType, optional, default: NoneType
            Request the sequence masked for repeat sequences. Hard will mask
            all repeats as N's and soft will mask repeats as lowercased
            characters. Only available when using genomic sequence type.
            Example values: 'hard'. Allowed values: hard,soft
        mask_feature : bool or NoneType, optional, default: NoneType
            Mask features on the sequence. If sequence is genomic, mask
            introns. If sequence is cDNA, mask UTRs. Incompatible with the
            'mask' option.
        object_type : str or NoneType, optional, default: NoneType
            Filter by feature type. Example values: 'gene'.
        species : str or NoneType, optional, default: NoneType
            Species name/alias. Example values: 'homo_sapiens'.
        start : int or NoneType, optional, default: NoneType
            Trim the start of the sequence by this many basepairs. Trimming is
            relative to reading direction and in the coordinate system of the
            stable identifier. Parameter can not be used in conjunction with
            expand_5prime or expand_3prime. Example values: '1000'.
        data_type : str or NoneType, optional, default: NoneType
            Type of sequence. Defaults to genomic where applicable, i.e. not
            translations. cdna refers to the spliced transcript sequence with
            UTR; cds refers to the spliced transcript sequence without UTR.
            Example values: 'cds'. Allowed values: genomic,cds,cdna,protein
        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 = 'POST'
        maximum_post_size = 50
        slice_length = 1e7
        endpoint = 'sequence/id'

        return self.rest_query(
            method_type,
            endpoint,
            maximum_post_size=maximum_post_size,
            slice_length=slice_length,
            ids=ids,
            db_type=db_type,
            end=end,
            expand_3prime=expand_3prime,
            expand_5prime=expand_5prime,
            format=data_format,
            mask=mask,
            mask_feature=mask_feature,
            object_type=object_type,
            species=species,
            start=start,
            type=data_type,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def get_sequence_region(self, region, species, coord_system=None,
                            coord_system_version=None, expand_3prime=None,
                            expand_5prime=None, data_format=None, mask=None,
                            mask_feature=None, norm_func=brc.default_pandas):
        """
        Returns the genomic sequence of the specified region of the given
        species. Supports feature masking and expand options. GET method.
        Queries:
        `sequence/region/:species/:region <https://rest.ensembl.org/documentation/info/sequence_region>`_.
        Max slice length: 1e7.

        Parameters
        ----------
        region : str
            Query region. A maximum of 10Mb is allowed to be requested at any
            one time. Example values: 'X:1000000..1000100:1
            X:1000000..1000100:-1 X:1000000..1000100'.
        species : str
            Species name/alias. Example values: 'homo_sapiens human'.
        coord_system : str or NoneType, optional, default: NoneType
            Filter by coordinate system name. Example values: 'contig
            seqlevel'.
        coord_system_version : str or NoneType, optional, default: NoneType
            Filter by coordinate system version. Example values: 'GRCh37'.
        expand_3prime : int or NoneType, optional, default: NoneType
            Expand the sequence downstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        expand_5prime : int or NoneType, optional, default: NoneType
            Expand the sequence upstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        data_format : str or NoneType, optional, default: NoneType
            Format of the data. Example values: 'fasta'. Allowed values: fasta
        mask : str or NoneType, optional, default: NoneType
            Request the sequence masked for repeat sequences. Hard will mask
            all repeats as N's and soft will mask repeats as lower cased
            characters. Only available when using genomic sequence type.
            Example values: 'hard'. Allowed values: hard,soft
        mask_feature : bool or NoneType, optional, default: NoneType
            Mask features on the sequence. If sequence is genomic, mask
            introns. If sequence is cDNA, mask UTRs. Incompatible with the
            'mask' option. Example values: '1'.
        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'
        slice_length = 1e7
        endpoint = 'sequence/region/{species}/{region}'.format(
            species=species,
            region=region
        )

        return self.rest_query(
            method_type,
            endpoint,
            slice_length=slice_length,
            coord_system=coord_system,
            coord_system_version=coord_system_version,
            expand_3prime=expand_3prime,
            expand_5prime=expand_5prime,
            format=data_format,
            mask=mask,
            mask_feature=mask_feature,
            norm_func=norm_func
        )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def post_sequence_region(self, species, regions, coord_system=None,
                             coord_system_version=None, expand_3prime=None,
                             expand_5prime=None, data_format=None, mask=None,
                             mask_feature=None, norm_func=brc.default_pandas):
        """
        Request multiple types of sequence by a list of regions. POST method.
        Queries:
        `sequence/region/:species <https://rest.ensembl.org/documentation/info/sequence_region_post>`_.
        Max post size: 50. Max slice length: 1e7.

        Parameters
        ----------
        species : str
            Species name/alias. Example values: 'homo_sapiens human'.
        regions : list
            Post option not defined in required/optional args.
        coord_system : str or NoneType, optional, default: NoneType
            Filter by coordinate system name. Example values: 'contig
            seqlevel'.
        coord_system_version : str or NoneType, optional, default: NoneType
            Filter by coordinate system version. Example values: 'GRCh37'.
        expand_3prime : int or NoneType, optional, default: NoneType
            Expand the sequence downstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        expand_5prime : int or NoneType, optional, default: NoneType
            Expand the sequence upstream of the sequence by this many
            basepairs. Only available when using genomic sequence type. Example
            values: '1000'.
        data_format : str or NoneType, optional, default: NoneType
            Format of the data. Example values: 'fasta'. Allowed values: fasta
        mask : str or NoneType, optional, default: NoneType
            Request the sequence masked for repeat sequences. Hard will mask
            all repeats as N's and soft will mask repeats as lower cased
            characters. Only available when using genomic sequence type.
            Example values: 'hard'. Allowed values: hard,soft
        mask_feature : bool or NoneType, optional, default: NoneType
            Mask features on the sequence. If sequence is genomic, mask
            introns. If sequence is cDNA, mask UTRs. Incompatible with the
            'mask' option. Example values: '1'.
        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 = 'POST'
        maximum_post_size = 50
        slice_length = 1e7
        endpoint = 'sequence/region/{species}'.format(
            species=species
        )

        return self.rest_query(
            method_type,
            endpoint,
            maximum_post_size=maximum_post_size,
            slice_length=slice_length,
            regions=regions,
            coord_system=coord_system,
            coord_system_version=coord_system_version,
            expand_3prime=expand_3prime,
            expand_5prime=expand_5prime,
            format=data_format,
            mask=mask,
            mask_feature=mask_feature,
            norm_func=norm_func
        )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class Sequence(brc._BaseRestClient, _Sequence):
    """Perform Sequence queries
    """
    pass
