# -*- coding: utf-8 -*-

import pytest

import datetime
import finoex
import ioex.datetimeex
import os
import pprint
import pytz
import yaml


def get_item_a():
    return finoex.Item(
        name=u'item',
        price_brutto=finoex.Sum(1.0, u'EUR'),
    )


def get_item_b():
    return finoex.Item(
        name=u'item',
        price_brutto=finoex.Sum(2.0, u'EUR'),
    )


def get_service_a():
    return finoex.Service(
        name=u'service',
        price_brutto=finoex.Sum(1.0, u'EUR'),
        duration=ioex.datetimeex.Duration(years=2),
    )


def get_service_b():
    return finoex.Service(
        name=u'service',
        price_brutto=finoex.Sum(1.0, u'EUR'),
        duration=ioex.datetimeex.Duration(),
    )


def get_discount_a():
    return finoex.Discount(
        name=u'discount',
        amount=finoex.Sum(1.0, u'EUR'),
    )


def get_discount_b():
    return finoex.Discount(
        name=u'discount',
        amount=finoex.Sum(2.0, u'EUR'),
    )


def get_order_a(items=True):
    order = finoex.Order(
        platform=u'platform',
        order_id=u'id',
        order_date=datetime.datetime(2016, 5, 8, 0, 18, 17),
        customer_id=u'customer',
    )
    if items:
        order.items.append(get_item_a())
        order.items.append(get_item_b())
    order.discounts.append(get_discount_a())
    order.discounts.append(get_discount_b())
    return order


def get_order_b():
    order = finoex.Order(
        platform=u'platform',
        order_id=u'id',
        order_date=datetime.datetime(2016, 5, 8, 0, 18, 17),
    )
    order.items.append(get_item_a())
    order.items.append(get_item_b())
    order.discounts.append(get_discount_a())
    order.discounts.append(get_discount_b())
    return order


def get_order_c():
    order = finoex.Order(
        platform=u'platform',
        order_id=u'id',
        order_date=datetime.datetime(2016, 5, 8, 0, 18, 17),
    )
    order.items.append(get_item_a())
    order.items.append(get_item_b())
    order.items.append(get_item_b())
    order.discounts.append(get_discount_a())
    order.discounts.append(get_discount_b())
    return order


def get_campaign_a():
    return finoex.Campaign(
        name=u'campaign a',
        founder=u'company',
        end=datetime.datetime(2016, 7, 23, 9, 23, 17, tzinfo=pytz.timezone('Europe/Vienna')),
    )


def get_campaign_b():
    return finoex.Campaign(
        name = u'campaign b',
        founder = u'company',
        end = datetime.datetime(2016, 7, 23, 9, 23, 17, tzinfo = pytz.timezone('Europe/Vienna')),
    )

def get_pledge_a():
    return finoex.Pledge(
        campaign=get_campaign_a(),
        price_brutto=finoex.Sum(10.0, u'EUR'),
    )


def get_pledge_b():
    return finoex.Pledge(
        campaign=get_campaign_a(),
        price_brutto=finoex.Sum(4.0, u'EUR'),
    )


def get_contribution_a():
    return finoex.Contribution(
        campaign=get_campaign_a(),
        price_brutto=finoex.Sum(10.0, u'EUR'),
    )


def get_contribution_b():
    return finoex.Contribution(
        campaign=get_campaign_a(),
        price_brutto=finoex.Sum(4.0, u'EUR'),
    )


def get_person_a():
    return finoex.Person(
        first_name=u'Fabian Peter',
        last_name=u'Hammerle',
    )


def get_person_b():
    return finoex.Person(
        first_name=u'名字',
        last_name=u'贵姓',
    )


def get_shipping():
    return finoex.Shipping(
        price_brutto=finoex.Sum(10.0, u'EUR'),
        destination_point=u'home',
    )


@pytest.mark.parametrize('a,b', [
    [ioex.calcex.Figure(1, u'mm'), ioex.calcex.Figure(1, u'mm')],
    [get_campaign_a(), get_campaign_a()],
    [get_campaign_b(), get_campaign_b()],
    [get_contribution_a(), get_contribution_a()],
    [get_contribution_b(), get_contribution_b()],
    [get_discount_a(), get_discount_a()],
    [get_discount_b(), get_discount_b()],
    [get_item_a(), get_item_a()],
    [get_item_b(), get_item_b()],
    [get_order_a(), get_order_a()],
    [get_order_b(), get_order_b()],
    [get_order_c(), get_order_c()],
    [get_person_a(), get_person_a()],
    [get_person_b(), get_person_b()],
    [get_pledge_a(), get_pledge_a()],
    [get_pledge_b(), get_pledge_b()],
    [get_service_a(), get_service_a()],
    [get_service_b(), get_service_b()],
    [get_shipping(), get_shipping()],
])
def test_eq(a, b):
    assert a == b, '\n'.join([
        'a = %r' % a,
        'b = %r' % b,
        'vars(a) = %s' % pprint.pformat(vars(a)),
        'vars(b) = %s' % pprint.pformat(vars(b)),
    ])
    assert b == a
    assert not a != b
    assert not b != a


@pytest.mark.parametrize('a,b', [
    [ioex.calcex.Figure(1, u'mm'), ioex.calcex.Figure(2, u'mm')],
    [get_contribution_a(), get_contribution_b()],
    [get_contribution_a(), get_item_b()],
    [get_discount_a(), get_discount_b()],
    [get_discount_a(), get_item_b()],
    [get_item_a(), get_item_b()],
    [get_order_a(), get_order_a(items=False)],
    [get_order_a(), get_order_b()],
    [get_order_a(), get_order_c()],
    [get_order_b(), get_order_c()],
    [get_person_a(), get_person_b()],
    [get_pledge_a(), get_contribution_b()],
    [get_pledge_a(), get_item_b()],
    [get_pledge_a(), get_pledge_b()],
    [get_service_a(), get_service_b()],
])
def test_neq(a, b):
    assert a != b
    assert b != a
    assert not a == b
    assert not b == a


def test_order_ne_items_reversed():
    order = get_order_a()
    order.items = order.items[::-1]
    assert get_order_a() != order