# pylint: disable=too-many-lines
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
from typing import Any, Callable, Dict, List, Optional, TypeVar

from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
from azure.core.pipeline import PipelineResponse
from azure.core.pipeline.transport import HttpResponse
from azure.core.rest import HttpRequest
from azure.core.tracing.decorator import distributed_trace
from azure.core.utils import case_insensitive_dict

from .. import models as _models
from ..._serialization import Serializer
from .._vendor import MixinABC, _convert_request
T = TypeVar('T')
ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]

_SERIALIZER = Serializer()
_SERIALIZER.client_side_validation = False

def build_entities_recognition_general_request(
    *,
    model_version: Optional[str] = None,
    show_stats: Optional[bool] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type = kwargs.pop('content_type', _headers.pop('Content-Type', None))  # type: Optional[str]
    accept = _headers.pop('Accept', "application/json, text/json")

    # Construct URL
    _url = kwargs.pop("template_url", "/entities/recognition/general")

    # Construct parameters
    if model_version is not None:
        _params['model-version'] = _SERIALIZER.query("model_version", model_version, 'str')
    if show_stats is not None:
        _params['showStats'] = _SERIALIZER.query("show_stats", show_stats, 'bool')

    # Construct headers
    if content_type is not None:
        _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str')
    _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str')

    return HttpRequest(
        method="POST",
        url=_url,
        params=_params,
        headers=_headers,
        **kwargs
    )


def build_entities_linking_request(
    *,
    model_version: Optional[str] = None,
    show_stats: Optional[bool] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type = kwargs.pop('content_type', _headers.pop('Content-Type', None))  # type: Optional[str]
    accept = _headers.pop('Accept', "application/json, text/json")

    # Construct URL
    _url = kwargs.pop("template_url", "/entities/linking")

    # Construct parameters
    if model_version is not None:
        _params['model-version'] = _SERIALIZER.query("model_version", model_version, 'str')
    if show_stats is not None:
        _params['showStats'] = _SERIALIZER.query("show_stats", show_stats, 'bool')

    # Construct headers
    if content_type is not None:
        _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str')
    _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str')

    return HttpRequest(
        method="POST",
        url=_url,
        params=_params,
        headers=_headers,
        **kwargs
    )


def build_key_phrases_request(
    *,
    model_version: Optional[str] = None,
    show_stats: Optional[bool] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type = kwargs.pop('content_type', _headers.pop('Content-Type', None))  # type: Optional[str]
    accept = _headers.pop('Accept', "application/json, text/json")

    # Construct URL
    _url = kwargs.pop("template_url", "/keyPhrases")

    # Construct parameters
    if model_version is not None:
        _params['model-version'] = _SERIALIZER.query("model_version", model_version, 'str')
    if show_stats is not None:
        _params['showStats'] = _SERIALIZER.query("show_stats", show_stats, 'bool')

    # Construct headers
    if content_type is not None:
        _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str')
    _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str')

    return HttpRequest(
        method="POST",
        url=_url,
        params=_params,
        headers=_headers,
        **kwargs
    )


def build_languages_request(
    *,
    model_version: Optional[str] = None,
    show_stats: Optional[bool] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type = kwargs.pop('content_type', _headers.pop('Content-Type', None))  # type: Optional[str]
    accept = _headers.pop('Accept', "application/json, text/json")

    # Construct URL
    _url = kwargs.pop("template_url", "/languages")

    # Construct parameters
    if model_version is not None:
        _params['model-version'] = _SERIALIZER.query("model_version", model_version, 'str')
    if show_stats is not None:
        _params['showStats'] = _SERIALIZER.query("show_stats", show_stats, 'bool')

    # Construct headers
    if content_type is not None:
        _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str')
    _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str')

    return HttpRequest(
        method="POST",
        url=_url,
        params=_params,
        headers=_headers,
        **kwargs
    )


def build_sentiment_request(
    *,
    model_version: Optional[str] = None,
    show_stats: Optional[bool] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type = kwargs.pop('content_type', _headers.pop('Content-Type', None))  # type: Optional[str]
    accept = _headers.pop('Accept', "application/json, text/json")

    # Construct URL
    _url = kwargs.pop("template_url", "/sentiment")

    # Construct parameters
    if model_version is not None:
        _params['model-version'] = _SERIALIZER.query("model_version", model_version, 'str')
    if show_stats is not None:
        _params['showStats'] = _SERIALIZER.query("show_stats", show_stats, 'bool')

    # Construct headers
    if content_type is not None:
        _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str')
    _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str')

    return HttpRequest(
        method="POST",
        url=_url,
        params=_params,
        headers=_headers,
        **kwargs
    )

class TextAnalyticsClientOperationsMixin(MixinABC):

    @distributed_trace
    def entities_recognition_general(
        self,
        documents: List[_models.MultiLanguageInput],
        model_version: Optional[str] = None,
        show_stats: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.EntitiesResult:
        """Named Entity Recognition.

        The API returns a list of general named entities in a given document. For the list of supported
        entity types, check :code:`<a href="https://aka.ms/taner">Supported Entity Types in Text
        Analytics API</a>`. See the :code:`<a href="https://aka.ms/talangs">Supported languages in Text
        Analytics API</a>` for the list of enabled languages.

        :param documents: The set of documents to process as part of this batch. Required.
        :type documents: list[~azure.ai.textanalytics.v3_0.models.MultiLanguageInput]
        :param model_version: (Optional) This value indicates which model will be used for scoring. If
         a model-version is not specified, the API should default to the latest, non-preview version.
         Default value is None.
        :type model_version: str
        :param show_stats: (Optional) if set to true, response will contain input and document level
         statistics. Default value is None.
        :type show_stats: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: EntitiesResult or the result of cls(response)
        :rtype: ~azure.ai.textanalytics.v3_0.models.EntitiesResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type = kwargs.pop('content_type', _headers.pop('Content-Type', "application/json"))  # type: str
        cls = kwargs.pop('cls', None)  # type: ClsType[_models.EntitiesResult]

        _input = _models.MultiLanguageBatchInput(documents=documents)
        _json = self._serialize.body(_input, 'MultiLanguageBatchInput')

        request = build_entities_recognition_general_request(
            model_version=model_version,
            show_stats=show_stats,
            content_type=content_type,
            json=_json,
            template_url=self.entities_recognition_general.metadata['url'],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        path_format_arguments = {
            "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
        }
        request.url = self._client.format_url(request.url, **path_format_arguments)  # type: ignore

        pipeline_response = self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            request,
            stream=False,
            **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, pipeline_response)
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize('EntitiesResult', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    entities_recognition_general.metadata = {'url': "/entities/recognition/general"}  # type: ignore


    @distributed_trace
    def entities_linking(
        self,
        documents: List[_models.MultiLanguageInput],
        model_version: Optional[str] = None,
        show_stats: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.EntityLinkingResult:
        """Linked entities from a well-known knowledge base.

        The API returns a list of recognized entities with links to a well-known knowledge base. See
        the :code:`<a href="https://aka.ms/talangs">Supported languages in Text Analytics API</a>` for
        the list of enabled languages.

        :param documents: The set of documents to process as part of this batch. Required.
        :type documents: list[~azure.ai.textanalytics.v3_0.models.MultiLanguageInput]
        :param model_version: (Optional) This value indicates which model will be used for scoring. If
         a model-version is not specified, the API should default to the latest, non-preview version.
         Default value is None.
        :type model_version: str
        :param show_stats: (Optional) if set to true, response will contain input and document level
         statistics. Default value is None.
        :type show_stats: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: EntityLinkingResult or the result of cls(response)
        :rtype: ~azure.ai.textanalytics.v3_0.models.EntityLinkingResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type = kwargs.pop('content_type', _headers.pop('Content-Type', "application/json"))  # type: str
        cls = kwargs.pop('cls', None)  # type: ClsType[_models.EntityLinkingResult]

        _input = _models.MultiLanguageBatchInput(documents=documents)
        _json = self._serialize.body(_input, 'MultiLanguageBatchInput')

        request = build_entities_linking_request(
            model_version=model_version,
            show_stats=show_stats,
            content_type=content_type,
            json=_json,
            template_url=self.entities_linking.metadata['url'],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        path_format_arguments = {
            "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
        }
        request.url = self._client.format_url(request.url, **path_format_arguments)  # type: ignore

        pipeline_response = self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            request,
            stream=False,
            **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, pipeline_response)
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize('EntityLinkingResult', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    entities_linking.metadata = {'url': "/entities/linking"}  # type: ignore


    @distributed_trace
    def key_phrases(
        self,
        documents: List[_models.MultiLanguageInput],
        model_version: Optional[str] = None,
        show_stats: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.KeyPhraseResult:
        """Key Phrases.

        The API returns a list of strings denoting the key phrases in the input text. See the :code:`<a
        href="https://aka.ms/talangs">Supported languages in Text Analytics API</a>` for the list of
        enabled languages.

        :param documents: The set of documents to process as part of this batch. Required.
        :type documents: list[~azure.ai.textanalytics.v3_0.models.MultiLanguageInput]
        :param model_version: (Optional) This value indicates which model will be used for scoring. If
         a model-version is not specified, the API should default to the latest, non-preview version.
         Default value is None.
        :type model_version: str
        :param show_stats: (Optional) if set to true, response will contain input and document level
         statistics. Default value is None.
        :type show_stats: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: KeyPhraseResult or the result of cls(response)
        :rtype: ~azure.ai.textanalytics.v3_0.models.KeyPhraseResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type = kwargs.pop('content_type', _headers.pop('Content-Type', "application/json"))  # type: str
        cls = kwargs.pop('cls', None)  # type: ClsType[_models.KeyPhraseResult]

        _input = _models.MultiLanguageBatchInput(documents=documents)
        _json = self._serialize.body(_input, 'MultiLanguageBatchInput')

        request = build_key_phrases_request(
            model_version=model_version,
            show_stats=show_stats,
            content_type=content_type,
            json=_json,
            template_url=self.key_phrases.metadata['url'],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        path_format_arguments = {
            "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
        }
        request.url = self._client.format_url(request.url, **path_format_arguments)  # type: ignore

        pipeline_response = self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            request,
            stream=False,
            **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, pipeline_response)
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize('KeyPhraseResult', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    key_phrases.metadata = {'url': "/keyPhrases"}  # type: ignore


    @distributed_trace
    def languages(
        self,
        documents: List[_models.LanguageInput],
        model_version: Optional[str] = None,
        show_stats: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.LanguageResult:
        """Detect Language.

        The API returns the detected language and a numeric score between 0 and 1. Scores close to 1
        indicate 100% certainty that the identified language is true. See the :code:`<a
        href="https://aka.ms/talangs">Supported languages in Text Analytics API</a>` for the list of
        enabled languages.

        :param documents: Required.
        :type documents: list[~azure.ai.textanalytics.v3_0.models.LanguageInput]
        :param model_version: (Optional) This value indicates which model will be used for scoring. If
         a model-version is not specified, the API should default to the latest, non-preview version.
         Default value is None.
        :type model_version: str
        :param show_stats: (Optional) if set to true, response will contain input and document level
         statistics. Default value is None.
        :type show_stats: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LanguageResult or the result of cls(response)
        :rtype: ~azure.ai.textanalytics.v3_0.models.LanguageResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type = kwargs.pop('content_type', _headers.pop('Content-Type', "application/json"))  # type: str
        cls = kwargs.pop('cls', None)  # type: ClsType[_models.LanguageResult]

        _input = _models.LanguageBatchInput(documents=documents)
        _json = self._serialize.body(_input, 'LanguageBatchInput')

        request = build_languages_request(
            model_version=model_version,
            show_stats=show_stats,
            content_type=content_type,
            json=_json,
            template_url=self.languages.metadata['url'],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        path_format_arguments = {
            "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
        }
        request.url = self._client.format_url(request.url, **path_format_arguments)  # type: ignore

        pipeline_response = self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            request,
            stream=False,
            **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, pipeline_response)
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize('LanguageResult', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    languages.metadata = {'url': "/languages"}  # type: ignore


    @distributed_trace
    def sentiment(
        self,
        documents: List[_models.MultiLanguageInput],
        model_version: Optional[str] = None,
        show_stats: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.SentimentResponse:
        """Sentiment.

        The API returns a sentiment prediction, as well as sentiment scores for each sentiment class
        (Positive, Negative, and Neutral) for the document and each sentence within it. See the
        :code:`<a href="https://aka.ms/talangs">Supported languages in Text Analytics API</a>` for the
        list of enabled languages.

        :param documents: The set of documents to process as part of this batch. Required.
        :type documents: list[~azure.ai.textanalytics.v3_0.models.MultiLanguageInput]
        :param model_version: (Optional) This value indicates which model will be used for scoring. If
         a model-version is not specified, the API should default to the latest, non-preview version.
         Default value is None.
        :type model_version: str
        :param show_stats: (Optional) if set to true, response will contain input and document level
         statistics. Default value is None.
        :type show_stats: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: SentimentResponse or the result of cls(response)
        :rtype: ~azure.ai.textanalytics.v3_0.models.SentimentResponse
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type = kwargs.pop('content_type', _headers.pop('Content-Type', "application/json"))  # type: str
        cls = kwargs.pop('cls', None)  # type: ClsType[_models.SentimentResponse]

        _input = _models.MultiLanguageBatchInput(documents=documents)
        _json = self._serialize.body(_input, 'MultiLanguageBatchInput')

        request = build_sentiment_request(
            model_version=model_version,
            show_stats=show_stats,
            content_type=content_type,
            json=_json,
            template_url=self.sentiment.metadata['url'],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        path_format_arguments = {
            "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
        }
        request.url = self._client.format_url(request.url, **path_format_arguments)  # type: ignore

        pipeline_response = self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            request,
            stream=False,
            **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, pipeline_response)
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize('SentimentResponse', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    sentiment.metadata = {'url': "/sentiment"}  # type: ignore

