# coding: utf-8

"""
Copyright 2017 Square, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
"""


from __future__ import absolute_import

import sys
import os
import re

# python 2 and python 3 compatibility library
from six import iteritems

from ..api_client import ApiClient


class CustomersApi(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

    def create_customer(self, body, **kwargs):
        """
        CreateCustomer
        Creates a new customer for a business, which can have associated cards on file.  You must provide __at least one__ of the following values in your request to this endpoint:  - `given_name` - `family_name` - `company_name` - `email_address` - `phone_number`

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.create_customer(body, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param CreateCustomerRequest body: An object containing the fields to POST for the request.  See the corresponding object definition for field details. (required)
        :return: CreateCustomerResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['body']
        all_params.append('callback')

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

        # verify the required parameter 'body' is set
        if ('body' not in params) or (params['body'] is None):
            raise ValueError("Missing the required parameter `body` when calling `create_customer`")


        resource_path = '/v2/customers'.replace('{format}', 'json')
        path_params = {}

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        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'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'POST',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='CreateCustomerResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def create_customer_card(self, customer_id, body, **kwargs):
        """
        CreateCustomerCard
        Adds a card on file to an existing customer.  As with charges, calls to `CreateCustomerCard` are idempotent. Multiple calls with the same card nonce return the same card record that was created with the provided nonce during the _first_ call.  Cards on file are automatically updated on a monthly basis to confirm they are still valid and can be charged.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.create_customer_card(customer_id, body, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str customer_id: The ID of the customer to link the card on file to. (required)
        :param CreateCustomerCardRequest body: An object containing the fields to POST for the request.  See the corresponding object definition for field details. (required)
        :return: CreateCustomerCardResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['customer_id', 'body']
        all_params.append('callback')

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

        # verify the required parameter 'customer_id' is set
        if ('customer_id' not in params) or (params['customer_id'] is None):
            raise ValueError("Missing the required parameter `customer_id` when calling `create_customer_card`")
        # verify the required parameter 'body' is set
        if ('body' not in params) or (params['body'] is None):
            raise ValueError("Missing the required parameter `body` when calling `create_customer_card`")


        resource_path = '/v2/customers/{customer_id}/cards'.replace('{format}', 'json')
        path_params = {}
        if 'customer_id' in params:
            path_params['customer_id'] = params['customer_id']

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        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'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'POST',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='CreateCustomerCardResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def delete_customer(self, customer_id, **kwargs):
        """
        DeleteCustomer
        Deletes a customer from a business, along with any linked cards on file. When two profiles are merged into a single profile, that profile is assigned a new `customer_id`. You must use the new `customer_id` to delete merged profiles.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.delete_customer(customer_id, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str customer_id: The ID of the customer to delete. (required)
        :return: DeleteCustomerResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['customer_id']
        all_params.append('callback')

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

        # verify the required parameter 'customer_id' is set
        if ('customer_id' not in params) or (params['customer_id'] is None):
            raise ValueError("Missing the required parameter `customer_id` when calling `delete_customer`")


        resource_path = '/v2/customers/{customer_id}'.replace('{format}', 'json')
        path_params = {}
        if 'customer_id' in params:
            path_params['customer_id'] = params['customer_id']

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        form_params = []
        local_var_files = {}

        body_params = None

        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.\
            select_header_accept(['application/json'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'DELETE',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='DeleteCustomerResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def delete_customer_card(self, customer_id, card_id, **kwargs):
        """
        DeleteCustomerCard
        Removes a card on file from a customer.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.delete_customer_card(customer_id, card_id, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str customer_id: The ID of the customer that the card on file belongs to. (required)
        :param str card_id: The ID of the card on file to delete. (required)
        :return: DeleteCustomerCardResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['customer_id', 'card_id']
        all_params.append('callback')

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

        # verify the required parameter 'customer_id' is set
        if ('customer_id' not in params) or (params['customer_id'] is None):
            raise ValueError("Missing the required parameter `customer_id` when calling `delete_customer_card`")
        # verify the required parameter 'card_id' is set
        if ('card_id' not in params) or (params['card_id'] is None):
            raise ValueError("Missing the required parameter `card_id` when calling `delete_customer_card`")


        resource_path = '/v2/customers/{customer_id}/cards/{card_id}'.replace('{format}', 'json')
        path_params = {}
        if 'customer_id' in params:
            path_params['customer_id'] = params['customer_id']
        if 'card_id' in params:
            path_params['card_id'] = params['card_id']

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        form_params = []
        local_var_files = {}

        body_params = None

        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.\
            select_header_accept(['application/json'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'DELETE',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='DeleteCustomerCardResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def list_customers(self, **kwargs):
        """
        ListCustomers
        Lists a business's customers.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.list_customers(callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str cursor: A pagination cursor returned by a previous call to this endpoint. Provide this to retrieve the next set of results for your original query.  See [Pagination](/basics/api101/pagination) for more information.
        :param str sort_field: Indicates how Customers should be sorted. Default: `DEFAULT`.
        :param str sort_order: Indicates whether Customers should be sorted in ascending (`ASC`) or descending (`DESC`) order. Default: `ASC`.
        :return: ListCustomersResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['cursor', 'sort_field', 'sort_order']
        all_params.append('callback')

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



        resource_path = '/v2/customers'.replace('{format}', 'json')
        path_params = {}

        query_params = {}
        if 'cursor' in params and params['cursor'] is not None:
            query_params['cursor'] = params['cursor']
        if 'sort_field' in params and params['sort_field'] is not None:
            query_params['sort_field'] = params['sort_field']
        if 'sort_order' in params and params['sort_order'] is not None:
            query_params['sort_order'] = params['sort_order']

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        form_params = []
        local_var_files = {}

        body_params = None

        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.\
            select_header_accept(['application/json'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'GET',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='ListCustomersResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def retrieve_customer(self, customer_id, **kwargs):
        """
        RetrieveCustomer
        Returns details for a single customer.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.retrieve_customer(customer_id, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str customer_id: The ID of the customer to retrieve. (required)
        :return: RetrieveCustomerResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['customer_id']
        all_params.append('callback')

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

        # verify the required parameter 'customer_id' is set
        if ('customer_id' not in params) or (params['customer_id'] is None):
            raise ValueError("Missing the required parameter `customer_id` when calling `retrieve_customer`")


        resource_path = '/v2/customers/{customer_id}'.replace('{format}', 'json')
        path_params = {}
        if 'customer_id' in params:
            path_params['customer_id'] = params['customer_id']

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        form_params = []
        local_var_files = {}

        body_params = None

        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.\
            select_header_accept(['application/json'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'GET',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='RetrieveCustomerResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def search_customers(self, body, **kwargs):
        """
        SearchCustomers
        Searches the customer profiles associated with a Square account. Calling SearchCustomers without an explicit query parameter returns all customer profiles ordered alphabetically based on `given_name` and `family_name`.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.search_customers(body, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param SearchCustomersRequest body: An object containing the fields to POST for the request.  See the corresponding object definition for field details. (required)
        :return: SearchCustomersResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['body']
        all_params.append('callback')

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

        # verify the required parameter 'body' is set
        if ('body' not in params) or (params['body'] is None):
            raise ValueError("Missing the required parameter `body` when calling `search_customers`")


        resource_path = '/v2/customers/search'.replace('{format}', 'json')
        path_params = {}

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        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'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'POST',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='SearchCustomersResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        

    def update_customer(self, customer_id, body, **kwargs):
        """
        UpdateCustomer
        Updates the details of an existing customer. When two profiles are merged into a single profile, that profile is assigned a new `customer_id`. You must use the new `customer_id` to update merged profiles.  You cannot edit a customer's cards on file with this endpoint. To make changes to a card on file, you must delete the existing card on file with the [DeleteCustomerCard](#endpoint-customers-deletecustomercard) endpoint, then create a new one with the [CreateCustomerCard](#endpoint-customers-createcustomercard) endpoint.

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please define a `callback` function
        to be invoked when receiving the response.
        >>> def callback_function(response):
        >>>     pprint(response)
        >>>
        >>> thread = api.update_customer(customer_id, body, callback=callback_function)

        :param callback function: The callback function
            for asynchronous request. (optional)
        :param str customer_id: The ID of the customer to update. (required)
        :param UpdateCustomerRequest body: An object containing the fields to POST for the request.  See the corresponding object definition for field details. (required)
        :return: UpdateCustomerResponse
                 If the method is called asynchronously,
                 returns the request thread.
        """

        all_params = ['customer_id', 'body']
        all_params.append('callback')

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

        # verify the required parameter 'customer_id' is set
        if ('customer_id' not in params) or (params['customer_id'] is None):
            raise ValueError("Missing the required parameter `customer_id` when calling `update_customer`")
        # verify the required parameter 'body' is set
        if ('body' not in params) or (params['body'] is None):
            raise ValueError("Missing the required parameter `body` when calling `update_customer`")


        resource_path = '/v2/customers/{customer_id}'.replace('{format}', 'json')
        path_params = {}
        if 'customer_id' in params:
            path_params['customer_id'] = params['customer_id']

        query_params = {}

        header_params = {}
        header_params['Square-Version'] = "2019-06-12"
        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'])
        if not header_params['Accept']:
            del header_params['Accept']

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

        # Authentication setting
        auth_settings = ['oauth2']

        return self.api_client.call_api(resource_path, 'PUT',
                                            path_params,
                                            query_params,
                                            header_params,
                                            body=body_params,
                                            post_params=form_params,
                                            files=local_var_files,
                                            response_type='UpdateCustomerResponse',
                                            auth_settings=auth_settings,
                                            callback=params.get('callback'))
        
