# -*- coding: utf-8 -*-

"""
    greenbyteapi

    This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ).
"""

from greenbyteapi.api_helper import APIHelper
from greenbyteapi.configuration import Configuration
from greenbyteapi.controllers.base_controller import BaseController
from greenbyteapi.http.auth.custom_header_auth import CustomHeaderAuth
from greenbyteapi.models.data_signal_item import DataSignalItem
from greenbyteapi.models.data_item import DataItem
from greenbyteapi.models.data_real_time_item import DataRealTimeItem
from greenbyteapi.models.data_per_category_response import DataPerCategoryResponse
from greenbyteapi.exceptions.problem_details_exception import ProblemDetailsException
from greenbyteapi.exceptions.api_exception import APIException

class DataController(BaseController):

    """A Controller to access Endpoints in the greenbyteapi API."""


    def get_data_signals(self,
                         device_ids):
        """Does a GET request to /datasignals.

        Gets authorized data signals for one or more devices.
        _🔐 This endpoint requires the **Data** endpoint permission._
        _This request can also be made using the POST method, 
        with a request to `datasignals.json` and 
        a JSON request body instead of query parameters._

        Args:
            device_ids (list of int): What devices to get data signals for.

        Returns:
            list of DataSignalItem: Response from the API. The data signals
                available for one or several of the devices.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/datasignals'
        _query_builder = Configuration.get_base_uri()
        _query_builder += _url_path
        _query_parameters = {
            'deviceIds': device_ids
        }
        _query_builder = APIHelper.append_url_with_query_parameters(_query_builder,
            _query_parameters, Configuration.array_serialization)
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.http_client.get(_query_url, headers=_headers)
        CustomHeaderAuth.apply(_request)
        _context = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _context.response.status_code == 400:
            raise ProblemDetailsException('The request cannot be fulfilled due to bad syntax.', _context)
        elif _context.response.status_code == 401:
            raise APIException('The request is missing a valid API key. ', _context)
        elif _context.response.status_code == 403:
            raise APIException('One of the following: * The API key does not authorize access to the requested endpoint because of a missing endpoint permission. * The API key does not authorize access to the requested data. Devices, sites or data signals can be limited. ', _context)
        elif _context.response.status_code == 405:
            raise APIException('The HTTP method is not allowed for the endpoint.', _context)
        elif _context.response.status_code == 429:
            raise ProblemDetailsException('The API key has been used in too many requests in a given amount of time. The following headers will be set in the response: * `X-Rate-Limit-Limit` – The rate limit period (for example   "1m", "12h", or "1d"). * `X-Rate-Limit-Remaining` – The remaining number of requests   for this period. * `X-Rate-Limit-Reset` – The UTC timestamp string (in ISO 8601   format) when the remaining number of requests resets.  The limit is currently 1,000 requests/minute per API key and IP address. ', _context)
        self.validate_response(_context)

        # Return appropriate type
        return APIHelper.json_deserialize(_context.response.raw_body, DataSignalItem.from_dictionary)

    def get_data(self,
                 device_ids,
                 data_signal_ids,
                 timestamp_start,
                 timestamp_end,
                 use_utc=False,
                 resolution='10minute',
                 aggregate='device',
                 aggregate_level=0,
                 calculation=None):
        """Does a GET request to /data.

        Gets data for multiple devices and data signals in the given
        resolution. The timestamps are in the time zone configured in the
        Greenbyte Platform.
        Use the useUtc flag to get timestamps in UTC for all resolutions other
        than daily, weekly, monthly and yearly.
        _🔐 This endpoint requires the **Data** endpoint permission._
        _This request can also be made using the POST method, 
        with a request to `data.json` and 
        a JSON request body instead of query parameters._

        Args:
            device_ids (list of int): Which devices to get data for.
            data_signal_ids (list of int): Which data signals to get data
                for.
            timestamp_start (datetime): The beginning of the time interval to
                get data for (inclusive), in [RFC 3339, section
                5.6](https://tools.ietf.org/html/rfc3339#section-5.6)
                **date-time** format:  * Timestamps ending with 'Z' are
                treated as UTC. Example: "2020-01-01T00:00:00Z" * Time zone
                (UTC) offset timestamps ending with '+HH:mm'/"-HH:mm" are also
                supported. Example: "2020-01-01T02:00:00-02:00" * Other
                timestamps are treated as being in the time zone configured in
                the Greenbyte Platform. Example: "2020-01-01T00:00:00"  The
                start timestamp **is** included in the time interval: for
                example, to select the full month of March 2020, set
                `timestampStart` to "2020-03-01T00:00:00" and `timestampEnd`
                to "2020-04-01T00:00:00".
            timestamp_end (datetime): The end of the time interval to get data
                for (exclusive), in [RFC 3339, section
                5.6](https://tools.ietf.org/html/rfc3339#section-5.6)
                **date-time** format:  * Timestamps ending with 'Z' are
                treated as UTC. Example: "2020-01-01T00:00:00Z" * Time zone
                (UTC) offset timestamps ending with '+HH:mm'/"-HH:mm" are also
                supported. Example: "2020-01-01T02:00:00-02:00" * Other
                timestamps are treated as being in the time zone configured in
                the Greenbyte Platform. Example: "2020-01-01T00:00:00"  The
                end timestamp is **not** included in the time interval: for
                example, to select the full month of March 2020, set
                `timestampStart` to "2020-03-01T00:00:00" and `timestampEnd`
                to "2020-04-01T00:00:00".
            use_utc (bool, optional): Set to true to get timestamps in UTC.
                UTC timestamps are available for all resolutions other than
                daily, weekly, monthly and yearly.
            resolution (ResolutionEnum, optional): The desired data
                resolution.
            aggregate (AggregateModeEnum, optional): How the data should be
                aggregated with regards to device(s) or site(s).
            aggregate_level (int, optional): When AggregateMode `siteLevel` is
                used this parameter controls down to which level in the
                hierarchy to aggregate.
            calculation (CalculationModeEnum, optional): The calculation used
                when aggregating data, both over time and across devices. The
                default is the data signal default.

        Returns:
            list of DataItem: Response from the API. The data grouped by data
                signal and aggregate.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/data'
        _query_builder = Configuration.get_base_uri()
        _query_builder += _url_path
        _query_parameters = {
            'deviceIds': device_ids,
            'dataSignalIds': data_signal_ids,
            'timestampStart': APIHelper.when_defined(APIHelper.RFC3339DateTime, timestamp_start),
            'timestampEnd': APIHelper.when_defined(APIHelper.RFC3339DateTime, timestamp_end),
            'useUtc': use_utc,
            'resolution': resolution,
            'aggregate': aggregate,
            'aggregateLevel': aggregate_level,
            'calculation': calculation
        }
        _query_builder = APIHelper.append_url_with_query_parameters(_query_builder,
            _query_parameters, Configuration.array_serialization)
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.http_client.get(_query_url, headers=_headers)
        CustomHeaderAuth.apply(_request)
        _context = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _context.response.status_code == 400:
            raise ProblemDetailsException('The request cannot be fulfilled due to bad syntax.', _context)
        elif _context.response.status_code == 401:
            raise APIException('The request is missing a valid API key. ', _context)
        elif _context.response.status_code == 403:
            raise APIException('One of the following: * The API key does not authorize access to the requested endpoint because of a missing endpoint permission. * The API key does not authorize access to the requested data. Devices, sites or data signals can be limited. ', _context)
        elif _context.response.status_code == 405:
            raise APIException('The HTTP method is not allowed for the endpoint.', _context)
        elif _context.response.status_code == 429:
            raise ProblemDetailsException('The API key has been used in too many requests in a given amount of time. The following headers will be set in the response: * `X-Rate-Limit-Limit` – The rate limit period (for example   "1m", "12h", or "1d"). * `X-Rate-Limit-Remaining` – The remaining number of requests   for this period. * `X-Rate-Limit-Reset` – The UTC timestamp string (in ISO 8601   format) when the remaining number of requests resets.  The limit is currently 1,000 requests/minute per API key and IP address. ', _context)
        self.validate_response(_context)

        # Return appropriate type
        return APIHelper.json_deserialize(_context.response.raw_body, DataItem.from_dictionary)

    def get_real_time_data(self,
                           device_ids,
                           data_signal_ids,
                           aggregate='device',
                           aggregate_level=0,
                           calculation=None):
        """Does a GET request to /realtimedata.

        Gets the most recent data point for each
        specified device and data signal. The timestamps are in UTC.
        _🔐 This endpoint requires the **Data** endpoint permission._
        _This request can also be made using the POST method, 
        with a request to `realtimedata.json` and 
        a JSON request body instead of query parameters._

        Args:
            device_ids (list of int): Which devices to get data for.
            data_signal_ids (list of int): Which data signals to get data
                for.
            aggregate (AggregateModeEnum, optional): How the data should be
                aggregated with regards to device(s) or site(s).
            aggregate_level (int, optional): When AggregateMode `siteLevel` is
                used this parameter controls down to which level in the
                hierarchy to aggregate.
            calculation (CalculationModeRealTimeEnum, optional): The
                calculation used when aggregating data, both over time and
                across devices. The default is the data signal default.

        Returns:
            list of DataRealTimeItem: Response from the API. The most recent
                data points grouped by data signal and aggregate.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/realtimedata'
        _query_builder = Configuration.get_base_uri()
        _query_builder += _url_path
        _query_parameters = {
            'deviceIds': device_ids,
            'dataSignalIds': data_signal_ids,
            'aggregate': aggregate,
            'aggregateLevel': aggregate_level,
            'calculation': calculation
        }
        _query_builder = APIHelper.append_url_with_query_parameters(_query_builder,
            _query_parameters, Configuration.array_serialization)
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.http_client.get(_query_url, headers=_headers)
        CustomHeaderAuth.apply(_request)
        _context = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _context.response.status_code == 400:
            raise ProblemDetailsException('The request cannot be fulfilled due to bad syntax.', _context)
        elif _context.response.status_code == 401:
            raise APIException('The request is missing a valid API key. ', _context)
        elif _context.response.status_code == 403:
            raise APIException('One of the following: * The API key does not authorize access to the requested endpoint because of a missing endpoint permission. * The API key does not authorize access to the requested data. Devices, sites or data signals can be limited. ', _context)
        elif _context.response.status_code == 405:
            raise APIException('The HTTP method is not allowed for the endpoint.', _context)
        elif _context.response.status_code == 429:
            raise ProblemDetailsException('The API key has been used in too many requests in a given amount of time. The following headers will be set in the response: * `X-Rate-Limit-Limit` – The rate limit period (for example   "1m", "12h", or "1d"). * `X-Rate-Limit-Remaining` – The remaining number of requests   for this period. * `X-Rate-Limit-Reset` – The UTC timestamp string (in ISO 8601   format) when the remaining number of requests resets.  The limit is currently 1,000 requests/minute per API key and IP address. ', _context)
        self.validate_response(_context)

        # Return appropriate type
        return APIHelper.json_deserialize(_context.response.raw_body, DataRealTimeItem.from_dictionary)

    def get_data_per_category(self,
                              device_ids,
                              data_signal_id,
                              timestamp_start,
                              timestamp_end,
                              aggregate='device',
                              aggregate_level=0,
                              category=None):
        """Does a GET request to /datapercategory.

        Gets signal data aggregated per availability contract category.
        _🔐 This endpoint requires the **Data** and **Statuses** endpoint
        permissions._
        _This request can also be made using the POST method, 
        with a request to `datapercategory.json` and 
        a JSON request body instead of query parameters._

        Args:
            device_ids (list of int): Which devices to get data for.
            data_signal_id (int): Which signal to get data for; only Lost
                Production signals are supported at the moment.
            timestamp_start (datetime): The beginning of the time interval to
                get data for (inclusive), in [RFC 3339, section
                5.6](https://tools.ietf.org/html/rfc3339#section-5.6)
                **date-time** format:  * Timestamps ending with 'Z' are
                treated as UTC. Example: "2020-01-01T00:00:00Z" * Time zone
                (UTC) offset timestamps ending with '+HH:mm'/"-HH:mm" are also
                supported. Example: "2020-01-01T02:00:00-02:00" * Other
                timestamps are treated as being in the time zone configured in
                the Greenbyte Platform. Example: "2020-01-01T00:00:00"  The
                start timestamp **is** included in the time interval: for
                example, to select the full month of March 2020, set
                `timestampStart` to "2020-03-01T00:00:00" and `timestampEnd`
                to "2020-04-01T00:00:00".
            timestamp_end (datetime): The end of the time interval to get data
                for (exclusive), in [RFC 3339, section
                5.6](https://tools.ietf.org/html/rfc3339#section-5.6)
                **date-time** format:  * Timestamps ending with 'Z' are
                treated as UTC. Example: "2020-01-01T00:00:00Z" * Time zone
                (UTC) offset timestamps ending with '+HH:mm'/"-HH:mm" are also
                supported. Example: "2020-01-01T02:00:00-02:00" * Other
                timestamps are treated as being in the time zone configured in
                the Greenbyte Platform. Example: "2020-01-01T00:00:00"  The
                end timestamp is **not** included in the time interval: for
                example, to select the full month of March 2020, set
                `timestampStart` to "2020-03-01T00:00:00" and `timestampEnd`
                to "2020-04-01T00:00:00".
            aggregate (AggregateModeEnum, optional): How the data should be
                aggregated with regards to device(s) or site(s).
            aggregate_level (int, optional): When AggregateMode `siteLevel` is
                used this parameter controls down to which level in the
                hierarchy to aggregate.
            category (list of StatusCategoryEnum, optional): Which status
                categories to include. By default all categories are
                included.

        Returns:
            DataPerCategoryResponse: Response from the API. The data grouped
                by aggregate (device, site, etc.) and contract category.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/datapercategory'
        _query_builder = Configuration.get_base_uri()
        _query_builder += _url_path
        _query_parameters = {
            'deviceIds': device_ids,
            'dataSignalId': data_signal_id,
            'timestampStart': APIHelper.when_defined(APIHelper.RFC3339DateTime, timestamp_start),
            'timestampEnd': APIHelper.when_defined(APIHelper.RFC3339DateTime, timestamp_end),
            'aggregate': aggregate,
            'aggregateLevel': aggregate_level,
            'category': category
        }
        _query_builder = APIHelper.append_url_with_query_parameters(_query_builder,
            _query_parameters, Configuration.array_serialization)
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.http_client.get(_query_url, headers=_headers)
        CustomHeaderAuth.apply(_request)
        _context = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _context.response.status_code == 400:
            raise ProblemDetailsException('The request cannot be fulfilled due to bad syntax.', _context)
        elif _context.response.status_code == 401:
            raise APIException('The request is missing a valid API key. ', _context)
        elif _context.response.status_code == 403:
            raise APIException('One of the following: * The API key does not authorize access to the requested endpoint because of a missing endpoint permission. * The API key does not authorize access to the requested data. Devices, sites or data signals can be limited. ', _context)
        elif _context.response.status_code == 405:
            raise APIException('The HTTP method is not allowed for the endpoint.', _context)
        elif _context.response.status_code == 429:
            raise ProblemDetailsException('The API key has been used in too many requests in a given amount of time. The following headers will be set in the response: * `X-Rate-Limit-Limit` – The rate limit period (for example   "1m", "12h", or "1d"). * `X-Rate-Limit-Remaining` – The remaining number of requests   for this period. * `X-Rate-Limit-Reset` – The UTC timestamp string (in ISO 8601   format) when the remaining number of requests resets.  The limit is currently 1,000 requests/minute per API key and IP address. ', _context)
        self.validate_response(_context)

        # Return appropriate type
        return APIHelper.json_deserialize(_context.response.raw_body, DataPerCategoryResponse.from_dictionary)
