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

"""
    moesifapi.controllers.api_controller


"""

from .base_controller import *
import gzip


class ApiController(BaseController):

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

    @classmethod
    def generate_post_payload(cls, body, headers):
        try:
            payload = gzip.compress(APIHelper.json_serialize(body).encode('utf-8'))
            headers['Content-Encoding'] = 'gzip'
        except:
            payload = APIHelper.json_serialize(body)
        return payload, headers

    def __init__(self, http_client = None, http_call_back = None):
        """Constructor which allows a different HTTP client for this controller."""
        BaseController.__init__(self, http_client, http_call_back)

    def create_event(self,
                     body):
        """Does a POST request to /v1/events.

        Add Single API Event Call

        Args:
            body (EventModel): TODO: type description here. Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/events'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Generate http payload
        _body, _headers = self.generate_post_payload(body, _headers)

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=_body)

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

        # Return response headers
        return _response.headers

    def create_events_batch(self,
                            body):
        """Does a POST request to /v1/events/batch.

        Add multiple API Events in a single batch (batch size must be less
        than 250kb)

        Args:
            body (list of EventModel): TODO: type description here.
                Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/events/batch'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Generate http payload
        _body, _headers = self.generate_post_payload(body, _headers)

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=_body)

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

        # Return response headers
        return _response.headers


    def update_user(self,
                     body):
        """Does a POST request to /v1/users.

        Update a single user

        Args:
            body (UserModel): TODO: type description here. Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/users'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

    def update_users_batch(self,
                            body):
        """Does a POST request to /v1/users/batch.

        Update multiple Users in a single batch (batch size must be less
        than 250kb)

        Args:
            body (list of UserModel): TODO: type description here.
                Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/users/batch'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back != None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

    def get_app_config(self):

        """Does a GET request to /v1/config.

        Get the application config

        Args: None

        Returns:
            Config for the application: Response from the API. success

        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.
        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/config'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id
        }

        # Prepare the API call.
        _request = self.http_client.get(_query_url, headers=_headers)

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

        return _response

    def get_governance_rules(self):
        # The base uri for api requests
        _query_builder = Configuration.BASE_URI
        # Prepare query string for API call
        _query_builder += '/v1/rules'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id
        }

        # Prepare the API call.
        _request = self.http_client.get(_query_url, headers=_headers)

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)


        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

        return _response

    def update_company(self,
                       body):
        """Does a POST request to /v1/companies.

        Update a single company

        Args:
            body (CompanyModel): TODO: type description here. Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/companies'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

    def update_companies_batch(self,
                               body):
        """Does a POST request to /v1/companies/batch.

        Update multiple companies in a single batch (batch size must be less
        than 250kb)

        Args:
            body (list of CompanyModel): TODO: type description here. Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/companies/batch'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

    def update_subscription(self,
                            body):
        """Does a POST request to /v1/subscriptions.

        Update a single subscription

        Args:
            body (SubscriptionModel): TODO: type description here. Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/subscriptions'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)

    def update_subscriptions_batch(self, body):
        """Does a POST request to /v1/subscriptions/batch.

        Update multiple subscriptions in a single batch (batch size must be less
        than 250kb)

        Args:
            body (list of SubscriptionModel): TODO: type description here.
                Example:

        Returns:
            void: Response from the API. success

        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.

        """

        # The base uri for api requests
        _query_builder = Configuration.BASE_URI

        # Prepare query string for API call
        _query_builder += '/v1/subscriptions/batch'

        # Validate and preprocess url
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8',
            'X-Moesif-Application-Id': Configuration.application_id,
            'User-Agent': Configuration.version,
        }

        # Prepare the API call.
        _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))

        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(_request)

        # Invoke the API call  to fetch the response.
        _response = self.http_client.execute_as_string(_request)

        # Wrap the request and the response in an HttpContext object
        _context = HttpContext(_request, _response)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(_context)

        # Global error handling using HTTP status codes.
        self.validate_response(_context)
