# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.pipeline import ClientRawResponse
from msrest.exceptions import HttpOperationError

from .. import models


class DigitalTwinOperations(object):
    """DigitalTwinOperations operations.

    :param client: Client for service requests.
    :param config: Configuration of service client.
    :param serializer: An object model serializer.
    :param deserializer: An object model deserializer.
    :ivar api_version: Version of the Api. Constant value: "2020-03-01".
    """

    models = models

    def __init__(self, client, config, serializer, deserializer):

        self._client = client
        self._serialize = serializer
        self._deserialize = deserializer

        self.config = config
        self.api_version = "2020-03-01"

    def get_digital_twin(self, digital_twin_id, custom_headers=None, raw=False, **operation_config):
        """Gets the digital twin.

        :param digital_twin_id: Digital Twin ID. Format of digitalTwinId is
         DeviceId[~ModuleId]. ModuleId is optional.
        :type digital_twin_id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_digital_twin.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str")
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_digital_twin.metadata = {"url": "/digitaltwins/{digitalTwinId}"}

    def update_digital_twin(
        self,
        digital_twin_id,
        digital_twin_patch,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Updates the digital twin.

        :param digital_twin_id: Digital Twin ID. Format of digitalTwinId is
         DeviceId[~ModuleId]. ModuleId is optional.
        :type digital_twin_id: str
        :param digital_twin_patch: Digital twin components to update.
        :type digital_twin_patch: dict[str, object]
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.update_digital_twin.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str")
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(digital_twin_patch, "{object}")

        # Construct and send request
        request = self._client.patch(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    update_digital_twin.metadata = {"url": "/digitaltwins/{digitalTwinId}"}

    def get_components(self, digital_twin_id, custom_headers=None, raw=False, **operation_config):
        """Gets the list of interfaces.

        :param digital_twin_id: Digital Twin ID. Format of digitalTwinId is
         DeviceId[~ModuleId]. ModuleId is optional.
        :type digital_twin_id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: DigitalTwinInterfaces or ClientRawResponse if raw=true
        :rtype: ~protocol.models.DigitalTwinInterfaces or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_components.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str")
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None
        header_dict = {}

        if response.status_code == 200:
            deserialized = self._deserialize("DigitalTwinInterfaces", response)
            header_dict = {"ETag": "str"}

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            client_raw_response.add_headers(header_dict)
            return client_raw_response

        return deserialized

    get_components.metadata = {"url": "/digitalTwins/{digitalTwinId}/interfaces"}

    def update_component(
        self,
        digital_twin_id,
        interfaces_patch_info,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Updates desired properties of multiple interfaces.
        Example URI: "digitalTwins/{digitalTwinId}/interfaces".

        :param digital_twin_id: Digital Twin ID. Format of digitalTwinId is
         DeviceId[~ModuleId]. ModuleId is optional.
        :type digital_twin_id: str
        :param interfaces_patch_info: Multiple interfaces desired properties
         to update.
        :type interfaces_patch_info:
         ~protocol.models.DigitalTwinInterfacesPatch
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: DigitalTwinInterfaces or ClientRawResponse if raw=true
        :rtype: ~protocol.models.DigitalTwinInterfaces or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.update_component.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str")
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(interfaces_patch_info, "DigitalTwinInterfacesPatch")

        # Construct and send request
        request = self._client.patch(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None
        header_dict = {}

        if response.status_code == 200:
            deserialized = self._deserialize("DigitalTwinInterfaces", response)
            header_dict = {"ETag": "str"}

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            client_raw_response.add_headers(header_dict)
            return client_raw_response

        return deserialized

    update_component.metadata = {"url": "/digitalTwins/{digitalTwinId}/interfaces"}

    def get_component(
        self, digital_twin_id, interface_name, custom_headers=None, raw=False, **operation_config
    ):
        """Gets the interface of given interfaceId.
        Example URI: "digitalTwins/{digitalTwinId}/interfaces/{interfaceName}".

        :param digital_twin_id: Digital Twin ID. Format of digitalTwinId is
         DeviceId[~ModuleId]. ModuleId is optional.
        :type digital_twin_id: str
        :param interface_name: The interface name.
        :type interface_name: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: DigitalTwinInterfaces or ClientRawResponse if raw=true
        :rtype: ~protocol.models.DigitalTwinInterfaces or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_component.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str"),
            "interfaceName": self._serialize.url("interface_name", interface_name, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None
        header_dict = {}

        if response.status_code == 200:
            deserialized = self._deserialize("DigitalTwinInterfaces", response)
            header_dict = {"ETag": "str"}

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            client_raw_response.add_headers(header_dict)
            return client_raw_response

        return deserialized

    get_component.metadata = {"url": "/digitalTwins/{digitalTwinId}/interfaces/{interfaceName}"}

    def get_digital_twin_model(
        self, model_id, expand=None, custom_headers=None, raw=False, **operation_config
    ):
        """Returns a DigitalTwin model definition for the given id.
        If "expand" is present in the query parameters and id is for a device
        capability model then it returns
        the capability metamodel with expanded interface definitions.

        :param model_id: Model id Ex:
         <example>urn:contoso:TemperatureSensor:1</example>
        :type model_id: str
        :param expand: Indicates whether to expand the device capability
         model's interface definitions inline or not.
         This query parameter ONLY applies to Capability model.
        :type expand: bool
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_digital_twin_model.metadata["url"]
        path_format_arguments = {"modelId": self._serialize.url("model_id", model_id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        if expand is not None:
            query_parameters["expand"] = self._serialize.query("expand", expand, "bool")
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 204]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None
        header_dict = {}

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)
            header_dict = {
                "ETag": "str",
                "x-ms-model-id": "str",
                "x-ms-model-resolution-status": "str",
                "x-ms-model-resolution-description": "str",
            }

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            client_raw_response.add_headers(header_dict)
            return client_raw_response

        return deserialized

    get_digital_twin_model.metadata = {"url": "/digitalTwins/models/{modelId}"}

    def update_digital_twin_model(
        self, model_id, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Updates the digital twin model content. If the content is empty or
        null, Digital twin model resolution status will be reset
        If content exists, then it will be updated with the uploaded content.

        :param model_id: Model id Ex:
         <example>urn:contoso:TemperatureSensor:1</example>
        :type model_id: str
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: None or ClientRawResponse if raw=true
        :rtype: None or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.update_digital_twin_model.metadata["url"]
        path_format_arguments = {"modelId": self._serialize.url("model_id", model_id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [204]:
            raise HttpOperationError(self._deserialize, response)

        if raw:
            client_raw_response = ClientRawResponse(None, response)
            client_raw_response.add_headers(
                {
                    "ETag": "str",
                    "x-ms-model-id": "str",
                    "x-ms-model-resolution-status": "str",
                    "x-ms-model-resolution-description": "str",
                }
            )
            return client_raw_response

    update_digital_twin_model.metadata = {"url": "/digitalTwins/models/{modelId}"}

    def invoke_component_command(
        self,
        digital_twin_id,
        interface_name,
        command_name,
        payload,
        connect_timeout_in_seconds=None,
        response_timeout_in_seconds=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Invoke a digital twin interface command.

        Invoke a digital twin interface command.

        :param digital_twin_id:
        :type digital_twin_id: str
        :param interface_name:
        :type interface_name: str
        :param command_name:
        :type command_name: str
        :param payload:
        :type payload: object
        :param connect_timeout_in_seconds: Connect timeout in seconds.
        :type connect_timeout_in_seconds: int
        :param response_timeout_in_seconds: Response timeout in seconds.
        :type response_timeout_in_seconds: int
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.invoke_component_command.metadata["url"]
        path_format_arguments = {
            "digitalTwinId": self._serialize.url("digital_twin_id", digital_twin_id, "str"),
            "interfaceName": self._serialize.url("interface_name", interface_name, "str"),
            "commandName": self._serialize.url("command_name", command_name, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )
        if connect_timeout_in_seconds is not None:
            query_parameters["connectTimeoutInSeconds"] = self._serialize.query(
                "connect_timeout_in_seconds", connect_timeout_in_seconds, "int"
            )
        if response_timeout_in_seconds is not None:
            query_parameters["responseTimeoutInSeconds"] = self._serialize.query(
                "response_timeout_in_seconds", response_timeout_in_seconds, "int"
            )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(payload, "object")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None
        header_dict = {}

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)
            header_dict = {"x-ms-command-statuscode": "int", "x-ms-request-id": "str"}

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            client_raw_response.add_headers(header_dict)
            return client_raw_response

        return deserialized

    invoke_component_command.metadata = {
        "url": "/digitalTwins/{digitalTwinId}/interfaces/{interfaceName}/commands/{commandName}"
    }
