# coding: utf-8

"""
    Klaviyo API

    Empowering creators to own their destiny  # noqa: E501

    OpenAPI spec version: 2021.11.26
    
    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

from __future__ import absolute_import

import re  # noqa: F401

# python 2 and python 3 compatibility library
import six

# retry imports
from custom_retry import retry_if_qualifies
import tenacity


from swagger_client.api_client import ApiClient


class ProfilesApi(object):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    Ref: https://github.com/swagger-api/swagger-codegen
    """

    def __init__(self, api_client=None):
        if api_client is None:
            api_client = ApiClient()
        self.api_client = api_client
        self.warned = []

    def exchange(self, **kwargs):  # noqa: E501
        """Exchange ID for Profile ID  # noqa: E501

        Swap Exchange ID / KX Token for Profile ID  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.exchange(async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param PeopleExchangeBody body:
        :return: InlineResponse2001
                 If the method is called asynchronously,
                 returns the request thread.
        """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.exchange_with_http_info(**kwargs)  # noqa: E501
        else:
            (data) = self.exchange_with_http_info(**kwargs)  # noqa: E501
            return data

    def exchange_with_http_info(self, **kwargs):  # noqa: E501
        """Exchange ID for Profile ID  # noqa: E501

        Swap Exchange ID / KX Token for Profile ID  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.exchange_with_http_info(async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param PeopleExchangeBody body:
        :return: InlineResponse2001
                 If the method is called asynchronously,
                 returns the request thread.
        """


        all_params = ['body']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')

        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method exchange" % key
                )
            params[key] = val
        del params['kwargs']

        collection_formats = {}

        path_params = {}

        query_params = []

        header_params = {}


        form_params = []
        local_var_files = {}

        body_params = None
        if 'body' in params:
            body_params = params['body']
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501

        # HTTP header `Content-Type`
        header_params['Content-Type'] = self.api_client.select_header_content_type(  # noqa: E501
            ['application/json'])  # noqa: E501

        # Authentication setting
        auth_settings = ['ApiKeyAuth']  # noqa: E501

        return self.api_client.call_api(
            '/v2/people/exchange', 'POST',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='InlineResponse2001',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)

    def get_profile(self, person_id, **kwargs):  # noqa: E501
        """Get Profile  # noqa: E501

        Retrieves all the data attributes for a person, based on the Klaviyo Person ID.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.get_profile(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :return: Person
                 If the method is called asynchronously,
                 returns the request thread.
        """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.get_profile_with_http_info(person_id, **kwargs)  # noqa: E501
        else:
            (data) = self.get_profile_with_http_info(person_id, **kwargs)  # noqa: E501
            return data

    def get_profile_with_http_info(self, person_id, **kwargs):  # noqa: E501
        """Get Profile  # noqa: E501

        Retrieves all the data attributes for a person, based on the Klaviyo Person ID.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.get_profile_with_http_info(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :return: Person
                 If the method is called asynchronously,
                 returns the request thread.
        """


        all_params = ['person_id']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')

        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_profile" % key
                )
            params[key] = val
        del params['kwargs']
        # verify the required parameter 'person_id' is set
        if ('person_id' not in params or
                params['person_id'] is None):
            raise ValueError("Missing the required parameter `person_id` when calling `get_profile`")  # noqa: E501

        collection_formats = {}

        path_params = {}
        if 'person_id' in params:
            path_params['person_id'] = params['person_id']  # noqa: E501

        query_params = []

        header_params = {}


        form_params = []
        local_var_files = {}

        body_params = None
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501

        # Authentication setting
        auth_settings = ['ApiKeyAuth']  # noqa: E501

        return self.api_client.call_api(
            '/v1/person/{person_id}', 'GET',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='Person',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)

    def profile_metric_timeline(self, person_id, metric_id, **kwargs):  # noqa: E501
        """Get Profile's Events for a Specific Metric  # noqa: E501

        Returns a person's batched timeline for one specific event type.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.profile_metric_timeline(person_id, metric_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param str metric_id: (required)
        :param str since: Either a 10-digit Unix timestamp (UTC) to use as starting datetime, OR a pagination token obtained from the next attribute of a prior API call. For backwards compatibility, UUIDs will continue to be supported for a limited time. Defaults to current time.
        :param int count: Number of events to return in a batch.
        :param str sort: Sort order to apply to timeline, either descending or ascending. Valid values are `desc` or `asc`. Defaults to `desc`.
        :return: MetricTimeline
                 If the method is called asynchronously,
                 returns the request thread.
        """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.profile_metric_timeline_with_http_info(person_id, metric_id, **kwargs)  # noqa: E501
        else:
            (data) = self.profile_metric_timeline_with_http_info(person_id, metric_id, **kwargs)  # noqa: E501
            return data

    def profile_metric_timeline_with_http_info(self, person_id, metric_id, **kwargs):  # noqa: E501
        """Get Profile's Events for a Specific Metric  # noqa: E501

        Returns a person's batched timeline for one specific event type.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.profile_metric_timeline_with_http_info(person_id, metric_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param str metric_id: (required)
        :param str since: Either a 10-digit Unix timestamp (UTC) to use as starting datetime, OR a pagination token obtained from the next attribute of a prior API call. For backwards compatibility, UUIDs will continue to be supported for a limited time. Defaults to current time.
        :param int count: Number of events to return in a batch.
        :param str sort: Sort order to apply to timeline, either descending or ascending. Valid values are `desc` or `asc`. Defaults to `desc`.
        :return: MetricTimeline
                 If the method is called asynchronously,
                 returns the request thread.
        """


        all_params = ['person_id', 'metric_id', 'since', 'count', 'sort']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')

        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method profile_metric_timeline" % key
                )
            params[key] = val
        del params['kwargs']
        # verify the required parameter 'person_id' is set
        if ('person_id' not in params or
                params['person_id'] is None):
            raise ValueError("Missing the required parameter `person_id` when calling `profile_metric_timeline`")  # noqa: E501
        # verify the required parameter 'metric_id' is set
        if ('metric_id' not in params or
                params['metric_id'] is None):
            raise ValueError("Missing the required parameter `metric_id` when calling `profile_metric_timeline`")  # noqa: E501

        collection_formats = {}

        path_params = {}
        if 'person_id' in params:
            path_params['person_id'] = params['person_id']  # noqa: E501
        if 'metric_id' in params:
            path_params['metric_id'] = params['metric_id']  # noqa: E501

        query_params = []
        if 'since' in params:
            query_params.append(('since', params['since']))  # noqa: E501
        if 'count' in params:
            query_params.append(('count', params['count']))  # noqa: E501
        if 'sort' in params:
            query_params.append(('sort', params['sort']))  # noqa: E501

        header_params = {}


        form_params = []
        local_var_files = {}

        body_params = None
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501

        # Authentication setting
        auth_settings = ['ApiKeyAuth']  # noqa: E501

        return self.api_client.call_api(
            '/v1/person/{person_id}/metric/{metric_id}/timeline', 'GET',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='MetricTimeline',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)

    def profile_metrics_timeline(self, person_id, **kwargs):  # noqa: E501
        """Get Profile's Events for all Metrics  # noqa: E501

        Returns a batched timeline of all events for a person.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.profile_metrics_timeline(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param str since: Either a 10-digit Unix timestamp (UTC) to use as starting datetime, OR a pagination token obtained from the next attribute of a prior API call. For backwards compatibility, UUIDs will continue to be supported for a limited time. Defaults to current time.
        :param int count: Number of events to return in a batch. Default = 50, Max = 100
        :param str sort: Sort order to apply to timeline, either descending or ascending. Valid values are `desc` or `asc`. Defaults to `desc`. Always descending when `since` is not sent, as `since` defaults to current time.
        :return: MetricTimeline
                 If the method is called asynchronously,
                 returns the request thread.
        """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.profile_metrics_timeline_with_http_info(person_id, **kwargs)  # noqa: E501
        else:
            (data) = self.profile_metrics_timeline_with_http_info(person_id, **kwargs)  # noqa: E501
            return data

    def profile_metrics_timeline_with_http_info(self, person_id, **kwargs):  # noqa: E501
        """Get Profile's Events for all Metrics  # noqa: E501

        Returns a batched timeline of all events for a person.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.profile_metrics_timeline_with_http_info(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param str since: Either a 10-digit Unix timestamp (UTC) to use as starting datetime, OR a pagination token obtained from the next attribute of a prior API call. For backwards compatibility, UUIDs will continue to be supported for a limited time. Defaults to current time.
        :param int count: Number of events to return in a batch. Default = 50, Max = 100
        :param str sort: Sort order to apply to timeline, either descending or ascending. Valid values are `desc` or `asc`. Defaults to `desc`. Always descending when `since` is not sent, as `since` defaults to current time.
        :return: MetricTimeline
                 If the method is called asynchronously,
                 returns the request thread.
        """


        all_params = ['person_id', 'since', 'count', 'sort']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')

        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method profile_metrics_timeline" % key
                )
            params[key] = val
        del params['kwargs']
        # verify the required parameter 'person_id' is set
        if ('person_id' not in params or
                params['person_id'] is None):
            raise ValueError("Missing the required parameter `person_id` when calling `profile_metrics_timeline`")  # noqa: E501

        collection_formats = {}

        path_params = {}
        if 'person_id' in params:
            path_params['person_id'] = params['person_id']  # noqa: E501

        query_params = []
        if 'since' in params:
            query_params.append(('since', params['since']))  # noqa: E501
        if 'count' in params:
            query_params.append(('count', params['count']))  # noqa: E501
        if 'sort' in params:
            query_params.append(('sort', params['sort']))  # noqa: E501

        header_params = {}


        form_params = []
        local_var_files = {}

        body_params = None
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501

        # Authentication setting
        auth_settings = ['ApiKeyAuth']  # noqa: E501

        return self.api_client.call_api(
            '/v1/person/{person_id}/metrics/timeline', 'GET',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='MetricTimeline',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)

    def update_profile(self, person_id, **kwargs):  # noqa: E501
        """Update Profile  # noqa: E501

        NOTE: If you are interested in creating or updating profiles in Klaviyo, you should be using the Identify API instead. The best use-case for this route is changing a profiles's email address or other primary identifier after a profile already exists in Klaviyo.  Add or update one more more attributes for a Person, based on the Klaviyo Person ID. If a property already exists, it will be updated. If a property is not set for that record, it will be created.  You can update any attribute, by sending one or more attributes along their new values, as query parameters. Recommended attributes for this endpoint: `$email`, `$phone_number`, `$id`   # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.update_profile(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param dict(str, object) params:
        :return: Person
                 If the method is called asynchronously,
                 returns the request thread.
        """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.update_profile_with_http_info(person_id, **kwargs)  # noqa: E501
        else:
            (data) = self.update_profile_with_http_info(person_id, **kwargs)  # noqa: E501
            return data

    def update_profile_with_http_info(self, person_id, **kwargs):  # noqa: E501
        """Update Profile  # noqa: E501

        NOTE: If you are interested in creating or updating profiles in Klaviyo, you should be using the Identify API instead. The best use-case for this route is changing a profiles's email address or other primary identifier after a profile already exists in Klaviyo.  Add or update one more more attributes for a Person, based on the Klaviyo Person ID. If a property already exists, it will be updated. If a property is not set for that record, it will be created.  You can update any attribute, by sending one or more attributes along their new values, as query parameters. Recommended attributes for this endpoint: `$email`, `$phone_number`, `$id`   # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True
        >>> thread = api.update_profile_with_http_info(person_id, async_req=True)
        >>> result = thread.get()

        :param async_req bool
        :param str person_id: (required)
        :param dict(str, object) params:
        :return: Person
                 If the method is called asynchronously,
                 returns the request thread.
        """


        all_params = ['person_id', 'params']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')

        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method update_profile" % key
                )
            params[key] = val
        del params['kwargs']
        # verify the required parameter 'person_id' is set
        if ('person_id' not in params or
                params['person_id'] is None):
            raise ValueError("Missing the required parameter `person_id` when calling `update_profile`")  # noqa: E501

        collection_formats = {}

        path_params = {}
        if 'person_id' in params:
            path_params['person_id'] = params['person_id']  # noqa: E501

        query_params = []
        if 'params' in params:
            query_params.append(('params', params['params']))  # noqa: E501

        header_params = {}


        form_params = []
        local_var_files = {}

        body_params = None
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501

        # Authentication setting
        auth_settings = ['ApiKeyAuth']  # noqa: E501

        return self.api_client.call_api(
            '/v1/person/{person_id}', 'PUT',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='Person',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)
