# coding=utf-8
from __future__ import unicode_literals, absolute_import
from hashlib import md5
import types
from django.conf import settings
import requests

def _smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Returns a bytestring version of 's', encoded as specified in 'encoding'.
    If strings_only is True, don't convert (some) non-string-like objects.
    """
    if strings_only and isinstance(s, (types.NoneType, int)):
        return s
    if not isinstance(s, basestring):
        try:
            return str(s)
        except UnicodeEncodeError:
            if isinstance(s, Exception):
                # An Exception subclass containing non-ASCII data that doesn't
                # know how to print itself properly. We shouldn't raise a
                # further exception.
                return ' '.join([_smart_str(arg, encoding, strings_only,
                                            errors) for arg in s])
            return unicode(s).encode(encoding, errors)
    elif isinstance(s, unicode):
        return s.encode(encoding, errors)
    elif s and encoding != 'utf-8':
        return s.decode('utf-8', errors).encode(encoding, errors)
    else:
        return s


def _params_filter(params, private_key):
    """
    对数组排序并除去字典中的空值和签名参数
    返回数组和链接串
    :param
        params: 待过滤字典
    :return (newparams, prestr)
        newsparams: 过滤后的新字典
        prestr: 待签名字符串
    """
    ks = params.keys()
    ks.sort()
    newparams = {}
    prestr = ''
    for k in ks:
        v = params[k]
        if k not in ('sign') and v != '':
            newparams[k] = v
            prestr += '{}={}&'.format(k, newparams[k])
    prestr = prestr + 'key={}'.format(private_key)
    return newparams, prestr


def _build_mysign(prestr, sign_type='MD5'):
    """
        生成签名结果
    """
    if sign_type == 'MD5':
        prestr = _smart_str(prestr)
        print repr(prestr), "*"
        return md5(prestr).hexdigest()
    return ''


def check_is_from_apple(resp_dict):
    sign = get_mysign(resp_dict)
    assert resp_dict['sign'] == sign

def get_mysign(params):
    # print params, "*"*10
    _, prestr = _params_filter(params, settings.APPLEPAY_MD5_KEY)
    return _build_mysign(prestr)


if __name__ == '__main__':
    params = {
        "bank_code": "98000008",
        "dt_order": "20160523143839",
        "info_order": "20160523143839",
        "money_order": "0.01",
        "no_order": "796267773068",
        "oid_partner": "201603031000747503",
        "oid_paybill": "2016052316877077",
        "pay_type": "R",
        "result_pay": "SUCCESS",
        "settle_date": "20160523",
        "sign": "0bc90bfc48015fdaf274642999212687",
        "sign_type": "MD5"
    }
    check_is_from_apple(params)
