# Copyright (c) 2008 Chris Moyer http://coredumped.org/
# Copyringt (c) 2010 Jason R. Coombs http://www.jaraco.com/
#
# 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 base64
import hmac
import hashlib
import urllib
import xml.sax
import uuid
import boto
import boto.utils
from boto import handler
from boto.connection import AWSQueryConnection
from boto.resultset import ResultSet
from boto.exception import FPSResponseError

class FPSConnection(AWSQueryConnection):

    APIVersion = '2007-01-08'

    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
                 is_secure=True, port=None, proxy=None, proxy_port=None,
                 proxy_user=None, proxy_pass=None,
                 host='fps.sandbox.amazonaws.com', debug=0,
                 https_connection_factory=None, path="/"):
        AWSQueryConnection.__init__(self, aws_access_key_id, aws_secret_access_key,
                                    is_secure, port, proxy, proxy_port,
                                    proxy_user, proxy_pass, host, debug,
                                    https_connection_factory, path)
    
    def _required_auth_capability(self):
        return ['fps']

    def install_payment_instruction(self, instruction, token_type="Unrestricted", transaction_id=None):
        """
        InstallPaymentInstruction
        instruction: The PaymentInstruction to send, for example: 
        
            MyRole=='Caller' orSay 'Roles do not match';
        
        token_type: Defaults to "Unrestricted"
        transaction_id: Defaults to a new ID
        """

        if(transaction_id == None):
            transaction_id = uuid.uuid4()
        params = {}
        params['PaymentInstruction'] = instruction
        params['TokenType'] = token_type
        params['CallerReference'] = transaction_id
        response = self.make_request("InstallPaymentInstruction", params)
        return response
    
    def install_caller_instruction(self, token_type="Unrestricted", transaction_id=None):
        """
        Set us up as a caller
        This will install a new caller_token into the FPS section.
        This should really only be called to regenerate the caller token.
        """
        response = self.install_payment_instruction("MyRole=='Caller';", token_type=token_type, transaction_id=transaction_id)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            caller_token = rs.TokenId
            try:
                boto.config.save_system_option("FPS", "caller_token", caller_token)
            except(IOError):
                boto.config.save_user_option("FPS", "caller_token", caller_token)
            return caller_token
        else:
            raise FPSResponseError(response.status, response.reason, body)

    def install_recipient_instruction(self, token_type="Unrestricted", transaction_id=None):
        """
        Set us up as a Recipient
        This will install a new caller_token into the FPS section.
        This should really only be called to regenerate the recipient token.
        """
        response = self.install_payment_instruction("MyRole=='Recipient';", token_type=token_type, transaction_id=transaction_id)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            recipient_token = rs.TokenId
            try:
                boto.config.save_system_option("FPS", "recipient_token", recipient_token)
            except(IOError):
                boto.config.save_user_option("FPS", "recipient_token", recipient_token)

            return recipient_token
        else:
            raise FPSResponseError(response.status, response.reason, body)

    def make_url(self, returnURL, paymentReason, pipelineName, transactionAmount, **params):
        """
        Generate the URL with the signature required for a transaction
        """
        # use the sandbox authorization endpoint if we're using the
        #  sandbox for API calls.
        endpoint_host = 'authorize.payments.amazon.com'
        if 'sandbox' in self.host:
            endpoint_host = 'authorize.payments-sandbox.amazon.com'
        base = "/cobranded-ui/actions/start"


        params['callerKey'] = str(self.aws_access_key_id)
        params['returnURL'] = str(returnURL)
        params['paymentReason'] = str(paymentReason)
        params['pipelineName'] = pipelineName
        params["signatureMethod"] = 'HmacSHA256'
        params["signatureVersion"] = '2'
        params["transactionAmount"] = transactionAmount

        if(not params.has_key('callerReference')):
            params['callerReference'] = str(uuid.uuid4())

        parts = ''
        for k in sorted(params.keys()):
            parts += "&%s=%s" % (k, urllib.quote(params[k], '~'))

        canonical = '\n'.join(['GET',
                               str(endpoint_host).lower(),
                               base,
                               parts[1:]])

        signature = self._auth_handler.sign_string(canonical)
        params["signature"] = signature

        urlsuffix = ''
        for k in sorted(params.keys()):
            urlsuffix += "&%s=%s" % (k, urllib.quote(params[k], '~'))
        urlsuffix = urlsuffix[1:] # strip the first &
        
        fmt = "https://%(endpoint_host)s%(base)s?%(urlsuffix)s"
        final = fmt % vars()
        return final

    def pay(self, transactionAmount, senderTokenId,
            recipientTokenId=None, callerTokenId=None,
            chargeFeeTo="Recipient",
            callerReference=None, senderReference=None, recipientReference=None,
            senderDescription=None, recipientDescription=None, callerDescription=None,
            metadata=None, transactionDate=None, reserve=False):
        """
        Make a payment transaction. You must specify the amount.
        This can also perform a Reserve request if 'reserve' is set to True.
        """
        params = {}
        params['SenderTokenId'] = senderTokenId
        # this is for 2008-09-17 specification
        params['TransactionAmount.Amount'] = str(transactionAmount)
        params['TransactionAmount.CurrencyCode'] = "USD"
        #params['TransactionAmount'] = str(transactionAmount)
        params['ChargeFeeTo'] = chargeFeeTo
        
        params['RecipientTokenId'] = (
            recipientTokenId if recipientTokenId is not None
            else boto.config.get("FPS", "recipient_token")
            )
        params['CallerTokenId'] = (
            callerTokenId if callerTokenId is not None
            else boto.config.get("FPS", "caller_token")
            )
        if(transactionDate != None):
            params['TransactionDate'] = transactionDate
        if(senderReference != None):
            params['SenderReference'] = senderReference
        if(recipientReference != None):
            params['RecipientReference'] = recipientReference
        if(senderDescription != None):
            params['SenderDescription'] = senderDescription
        if(recipientDescription != None):
            params['RecipientDescription'] = recipientDescription
        if(callerDescription != None):
            params['CallerDescription'] = callerDescription
        if(metadata != None):
            params['MetaData'] = metadata
        if(callerReference == None):
            callerReference = uuid.uuid4()
        params['CallerReference'] = callerReference
        
        if reserve:
            response = self.make_request("Reserve", params)
        else:
            response = self.make_request("Pay", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def get_transaction_status(self, transactionId):
        """
        Returns the status of a given transaction.
        """
        params = {}
        params['TransactionId'] = transactionId
    
        response = self.make_request("GetTransactionStatus", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def cancel(self, transactionId, description=None):
        """
        Cancels a reserved or pending transaction.
        """
        params = {}
        params['transactionId'] = transactionId
        if(description != None):
            params['description'] = description
        
        response = self.make_request("Cancel", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def settle(self, reserveTransactionId, transactionAmount=None):
        """
        Charges for a reserved payment.
        """
        params = {}
        params['ReserveTransactionId'] = reserveTransactionId
        if(transactionAmount != None):
            params['TransactionAmount'] = transactionAmount
        
        response = self.make_request("Settle", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def refund(self, callerReference, transactionId, refundAmount=None, callerDescription=None):
        """
        Refund a transaction. This refunds the full amount by default unless 'refundAmount' is specified.
        """
        params = {}
        params['CallerReference'] = callerReference
        params['TransactionId'] = transactionId
        if(refundAmount != None):
            params['RefundAmount'] = refundAmount
        if(callerDescription != None):
            params['CallerDescription'] = callerDescription
        
        response = self.make_request("Refund", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def get_recipient_verification_status(self, recipientTokenId):
        """
        Test that the intended recipient has a verified Amazon Payments account.
        """
        params ={}
        params['RecipientTokenId'] = recipientTokenId
        
        response = self.make_request("GetRecipientVerificationStatus", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    
    def get_token_by_caller_reference(self, callerReference):
        """
        Returns details about the token specified by 'callerReference'.
        """
        params ={}
        params['callerReference'] = callerReference
        
        response = self.make_request("GetTokenByCaller", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
    def get_token_by_caller_token(self, tokenId):
        """
        Returns details about the token specified by 'callerReference'.
        """
        params ={}
        params['TokenId'] = tokenId
        
        response = self.make_request("GetTokenByCaller", params)
        body = response.read()
        if(response.status == 200):
            rs = ResultSet()
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)

    def verify_signature(self, end_point_url, http_parameters):
        params = dict(
            UrlEndPoint = end_point_url,
            HttpParameters = http_parameters,
            )
        response = self.make_request("VerifySignature", params)
        body = response.read()
        if(response.status != 200):
            raise FPSResponseError(response.status, response.reason, body)
        rs = ResultSet()
        h = handler.XmlHandler(rs, self)
        xml.sax.parseString(body, h)
        return rs
