# Copyright (c) 2012 Andy Davidoff http://www.disruptek.com/
# Copyright (c) 2010 Jason R. Coombs http://www.jaraco.com/
# Copyright (c) 2008 Chris Moyer http://coredumped.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

import urllib
import uuid
from boto.connection import AWSQueryConnection
from boto.fps.exception import ResponseErrorFactory
from boto.fps.response import ResponseFactory
import boto.fps.response

__all__ = ['FPSConnection']

decorated_attrs = ('action', 'response')


def add_attrs_from(func, to):
    for attr in decorated_attrs:
        setattr(to, attr, getattr(func, attr, None))
    return to


def complex_amounts(*fields):
    def decorator(func):
        def wrapper(self, *args, **kw):
            for field in filter(kw.has_key, fields):
                amount = kw.pop(field)
                kw[field + '.Value'] = getattr(amount, 'Value', str(amount))
                kw[field + '.CurrencyCode'] = getattr(amount, 'CurrencyCode',
                                                      self.currencycode)
            return func(self, *args, **kw)
        wrapper.__doc__ = "{0}\nComplex Amounts: {1}".format(func.__doc__,
                                                 ', '.join(fields))
        return add_attrs_from(func, to=wrapper)
    return decorator


def requires(*groups):

    def decorator(func):

        def wrapper(*args, **kw):
            hasgroup = lambda x: len(x) == len(filter(kw.has_key, x))
            if 1 != len(filter(hasgroup, groups)):
                message = ' OR '.join(['+'.join(g) for g in groups])
                message = "{0} requires {1} argument(s)" \
                          "".format(getattr(func, 'action', 'Method'), message)
                raise KeyError(message)
            return func(*args, **kw)
        message = ' OR '.join(['+'.join(g) for g in groups])
        wrapper.__doc__ = "{0}\nRequired: {1}".format(func.__doc__,
                                                           message)
        return add_attrs_from(func, to=wrapper)
    return decorator


def needs_caller_reference(func):

    def wrapper(*args, **kw):
        kw.setdefault('CallerReference', uuid.uuid4())
        return func(*args, **kw)
    wrapper.__doc__ = "{0}\nUses CallerReference, defaults " \
                      "to uuid.uuid4()".format(func.__doc__)
    return add_attrs_from(func, to=wrapper)


def api_action(*api):

    def decorator(func):
        action = ''.join(api or map(str.capitalize, func.func_name.split('_')))
        response = ResponseFactory(action)
        if hasattr(boto.fps.response, action + 'Response'):
            response = getattr(boto.fps.response, action + 'Response')

        def wrapper(self, *args, **kw):
            return func(self, action, response, *args, **kw)
        wrapper.action, wrapper.response = action, response
        wrapper.__doc__ = "FPS {0} API call\n{1}".format(action,
                                                         func.__doc__)
        return wrapper
    return decorator


class FPSConnection(AWSQueryConnection):

    APIVersion = '2010-08-28'
    ResponseError = ResponseErrorFactory
    currencycode = 'USD'

    def __init__(self, *args, **kw):
        self.currencycode = kw.pop('CurrencyCode', self.currencycode)
        kw.setdefault('host', 'fps.sandbox.amazonaws.com')
        AWSQueryConnection.__init__(self, *args, **kw)

    def _required_auth_capability(self):
        return ['fps']

    @needs_caller_reference
    @complex_amounts('SettlementAmount')
    @requires(['CreditInstrumentId', 'SettlementAmount.Value',
               'SenderTokenId',      'SettlementAmount.CurrencyCode'])
    @api_action()
    def settle_debt(self, action, response, **kw):
        """Allows a caller to initiate a transaction that atomically
           transfers money from a sender's payment instrument to the
           recipient, while decreasing corresponding debt balance.
        """
        return self.get_object(action, kw, response)

    @requires(['TransactionId'])
    @api_action()
    def get_transaction_status(self, action, response, **kw):
        """Gets the latest status of a transaction.
        """
        return self.get_object(action, kw, response)

    @requires(['StartDate'])
    @api_action()
    def get_account_activity(self, action, response, **kw):
        """Returns transactions for a given date range.
        """
        return self.get_object(action, kw, response)

    @requires(['TransactionId'])
    @api_action()
    def get_transaction(self, action, response, **kw):
        """Returns all details of a transaction.
        """
        return self.get_object(action, kw, response)

    @api_action()
    def get_outstanding_debt_balance(self, action, response):
        """Returns the total outstanding balance for all the credit
           instruments for the given creditor account.
        """
        return self.get_object(action, {}, response)

    @requires(['PrepaidInstrumentId'])
    @api_action()
    def get_prepaid_balance(self, action, response, **kw):
        """Returns the balance available on the given prepaid instrument.
        """
        return self.get_object(action, kw, response)

    @api_action()
    def get_total_prepaid_liability(self, action, response):
        """Returns the total liability held by the given account
           corresponding to all the prepaid instruments owned by the
           account.
        """
        return self.get_object(action, {}, response)

    @api_action()
    def get_account_balance(self, action, response):
        """Returns the account balance for an account in real time.
        """
        return self.get_object(action, {}, response)

    @needs_caller_reference
    @requires(['PaymentInstruction', 'TokenType'])
    @api_action()
    def install_payment_instruction(self, action, response, **kw):
        """Installs a payment instruction for caller.
        """
        return self.get_object(action, kw, response)

    @needs_caller_reference
    @requires(['returnURL', 'pipelineName'])
    def cbui_url(self, **kw):
        """Generate a signed URL for the Co-Branded service API given
           arguments as payload.
        """
        sandbox = 'sandbox' in self.host and 'payments-sandbox' or 'payments'
        endpoint = 'authorize.{0}.amazon.com'.format(sandbox)
        base = '/cobranded-ui/actions/start'

        validpipelines = ('SingleUse', 'MultiUse', 'Recurring', 'Recipient',
                          'SetupPrepaid', 'SetupPostpaid', 'EditToken')
        assert kw['pipelineName'] in validpipelines, "Invalid pipelineName"
        kw.update({
            'signatureMethod':  'HmacSHA256',
            'signatureVersion': '2',
        })
        kw.setdefault('callerKey', self.aws_access_key_id)

        safestr = lambda x: x is not None and str(x) or ''
        safequote = lambda x: urllib.quote(safestr(x), safe='~')
        payload = sorted([(k, safequote(v)) for k, v in kw.items()])

        encoded = lambda p: '&'.join([k + '=' + v for k, v in p])
        canonical = '\n'.join(['GET', endpoint, base, encoded(payload)])
        signature = self._auth_handler.sign_string(canonical)
        payload += [('signature', safequote(signature))]
        payload.sort()

        return 'https://{0}{1}?{2}'.format(endpoint, base, encoded(payload))

    @needs_caller_reference
    @complex_amounts('TransactionAmount')
    @requires(['SenderTokenId', 'TransactionAmount.Value',
                                'TransactionAmount.CurrencyCode'])
    @api_action()
    def reserve(self, action, response, **kw):
        """Reserve API is part of the Reserve and Settle API conjunction
           that serve the purpose of a pay where the authorization and
           settlement have a timing difference.
        """
        return self.get_object(action, kw, response)

    @needs_caller_reference
    @complex_amounts('TransactionAmount')
    @requires(['SenderTokenId', 'TransactionAmount.Value',
                                'TransactionAmount.CurrencyCode'])
    @api_action()
    def pay(self, action, response, **kw):
        """Allows calling applications to move money from a sender to
           a recipient.
        """
        return self.get_object(action, kw, response)

    @requires(['TransactionId'])
    @api_action()
    def cancel(self, action, response, **kw):
        """Cancels an ongoing transaction and puts it in cancelled state.
        """
        return self.get_object(action, kw, response)

    @complex_amounts('TransactionAmount')
    @requires(['ReserveTransactionId', 'TransactionAmount.Value',
                                       'TransactionAmount.CurrencyCode'])
    @api_action()
    def settle(self, action, response, **kw):
        """The Settle API is used in conjunction with the Reserve API and
           is used to settle previously reserved transaction.
        """
        return self.get_object(action, kw, response)

    @complex_amounts('RefundAmount')
    @requires(['TransactionId',   'RefundAmount.Value',
               'CallerReference', 'RefundAmount.CurrencyCode'])
    @api_action()
    def refund(self, action, response, **kw):
        """Refunds a previously completed transaction.
        """
        return self.get_object(action, kw, response)

    @requires(['RecipientTokenId'])
    @api_action()
    def get_recipient_verification_status(self, action, response, **kw):
        """Returns the recipient status.
        """
        return self.get_object(action, kw, response)

    @requires(['CallerReference'], ['TokenId'])
    @api_action()
    def get_token_by_caller(self, action, response, **kw):
        """Returns the details of a particular token installed by this
           calling application using the subway co-branded UI.
        """
        return self.get_object(action, kw, response)

    @requires(['UrlEndPoint', 'HttpParameters'])
    @api_action()
    def verify_signature(self, action, response, **kw):
        """Verify the signature that FPS sent in IPN or callback urls.
        """
        return self.get_object(action, kw, response)

    @api_action()
    def get_tokens(self, action, response, **kw):
        """Returns a list of tokens installed on the given account.
        """
        return self.get_object(action, kw, response)

    @requires(['TokenId'])
    @api_action()
    def get_token_usage(self, action, response, **kw):
        """Returns the usage of a token.
        """
        return self.get_object(action, kw, response)

    @requires(['TokenId'])
    @api_action()
    def cancel_token(self, action, response, **kw):
        """Cancels any token installed by the calling application on
           its own account.
        """
        return self.get_object(action, kw, response)

    @needs_caller_reference
    @complex_amounts('FundingAmount')
    @requires(['PrepaidInstrumentId', 'FundingAmount.Value',
               'SenderTokenId',       'FundingAmount.CurrencyCode'])
    @api_action()
    def fund_prepaid(self, action, response, **kw):
        """Funds the prepaid balance on the given prepaid instrument.
        """
        return self.get_object(action, kw, response)

    @requires(['CreditInstrumentId'])
    @api_action()
    def get_debt_balance(self, action, response, **kw):
        """Returns the balance corresponding to the given credit instrument.
        """
        return self.get_object(action, kw, response)

    @needs_caller_reference
    @complex_amounts('AdjustmentAmount')
    @requires(['CreditInstrumentId', 'AdjustmentAmount.Value',
                                     'AdjustmentAmount.CurrencyCode'])
    @api_action()
    def write_off_debt(self, action, response, **kw):
        """Allows a creditor to write off the debt balance accumulated
           partially or fully at any time.
        """
        return self.get_object(action, kw, response)

    @requires(['SubscriptionId'])
    @api_action()
    def get_transactions_for_subscription(self, action, response, **kw):
        """Returns the transactions for a given subscriptionID.
        """
        return self.get_object(action, kw, response)

    @requires(['SubscriptionId'])
    @api_action()
    def get_subscription_details(self, action, response, **kw):
        """Returns the details of Subscription for a given subscriptionID.
        """
        return self.get_object(action, kw, response)

    @needs_caller_reference
    @complex_amounts('RefundAmount')
    @requires(['SubscriptionId'])
    @api_action()
    def cancel_subscription_and_refund(self, action, response, **kw):
        """Cancels a subscription.
        """
        message = "If you specify a RefundAmount, " \
                  "you must specify CallerReference."
        assert not 'RefundAmount.Value' in kw \
                or 'CallerReference' in kw, message
        return self.get_object(action, kw, response)

    @requires(['TokenId'])
    @api_action()
    def get_payment_instruction(self, action, response, **kw):
        """Gets the payment instruction of a token.
        """
        return self.get_object(action, kw, response)
