## $Id: paypal.py 12060 2014-11-25 18:44:01Z uli $
##
## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
"""Support for PayPal payments.
"""
import ConfigParser
import paypalrestsdk
from zope.component import queryUtility
from waeup.ikoba.interfaces import IPayPalConfig


def parse_paypal_config(path):
    """Get paypal credentials from config file.

    Returns a dict with following keys set:

      ``client_id``, ``client_secret``, ``mode``.

    Please note, that values might be `None`.
    """
    parser = ConfigParser.SafeConfigParser(
        {'id': None, 'secret': None, 'mode': 'sandbox', }
        )
    parser.readfp(open(path))
    return {
        'client_id': parser.get('rest-client', 'id', None),
        'client_secret': parser.get('rest-client', 'secret', None),
        'mode': parser.get('rest-client', 'mode', 'sandbox')
        }


def get_paypal_config_file_path():
    """Get the path of the configuration file (if any).

    If no such file is registered, we get `None`.
    """
    util = queryUtility(IPayPalConfig)
    if util is None:
        return None
    return util['path']


def configure_sdk(path):
    """Configure the PayPal SDK with values from config in `path`.

    Parse paypal configuration from file in `path` and set
    configuration in SDK accordingly.

    Returns a dict with values from config file and path set.

    This function will normally be called during start-up and only
    this one time.

    It is neccessary to authorize later calls to other part of the
    PayPal API.
    """
    conf = parse_paypal_config(path)
    paypalrestsdk.configure({
        'mode': conf['mode'],
        'client_id': conf['client_id'],
        'client_secret': conf['client_secret'],
        })
    conf['path'] = path
    return conf


def get_access_token():
    """Get an access token for further calls.
    """
    conf = parse_paypal_config(get_paypal_config_file_path())
    api = paypalrestsdk.set_config(
        mode=conf['mode'],  # sandbox or live
        client_id=conf['client_id'],
        client_secret=conf['client_secret'],
        )
    return api.get_access_token()


def get_payment():
    """Construct a payment.

    You have to `create()` the payment yourself.

    XXX: Just some sampledata yet.
    """
    payment = paypalrestsdk.Payment(
        {
            "intent": "sale",
            "payer": {
                "payment_method": "credit_card",
                "funding_instruments": [
                    {
                        "credit_card": {
                            "type": "visa",
                            "number": "4417119669820331",
                            "expire_month": "11",
                            "expire_year": "2018",
                            "cvv2": "874",
                            "first_name": "Joe",
                            "last_name": "Shopper",
                            "billing_address": {
                                "line1": "52 N Main ST",
                                "city": "Johnstown",
                                "state": "OH",
                                "postal_code": "43210",
                                "country_code": "US"}
                            }
                        }
                    ]},
            "transactions": [{
                    "amount": {
                        "total": "7.47",
                        "currency": "USD",
                        "details": {
                            "subtotal": "7.41",
                            "tax": "0.03",
                            "shipping": "0.03"}},
                    "description": ("This is the payment "
                                    "transaction description.")
                    }]
            }
        )
    return payment
