from decimal import Decimal
from datetime import datetime, date, time, timedelta
import dateutil.parser


def generate_set_testcases():
	cases = [
		set(e)
		for e in [
			{ 1, 2, 3 },
			{ 3, 5, 6 },
			{ 1, 1, 1 }
		]
	]
	for case in cases:
		yield str(case), (set, case)


def generate_frozenset_testcases():
	cases = [
		frozenset(e)
		for e in [
			{ 1, 2, 3 },
			{ 3, 5, 6 },
			{ 1, 1, 1 }
		]
	]
	for case in cases:
		yield str(case), (frozenset, case)


def generate_decimal_testcases():
	cases = [
		Decimal(e)
		for e in [ '0.142857', '3.14598', '454698.89846479743']
	]
	for case in cases:
		yield str(case), (Decimal, case)


def generate_datetime_testcases():
	cases = [
		dateutil.parser.parse(e)
		for e in [
			'2017-07-19T08:24:50-06:00', '2017-02-05T04:16:36-06:00', '1970-12-25T01:00:24+02:00',
			'1970-12-25T01:00:24+00:00', '1970-12-25T01:00:24'
		]
	]
	for case in cases:
		yield str(case), (datetime, case)


def generate_date_testcases():
	cases = [
		dateutil.parser.parse(e).date()
		for e in [
			'2017-07-19', '2029-02-05', '1985-12-25',
			'1995-12-25', '2010-12-25'
		]
	]
	for case in cases:
		yield str(case), (date, case)


def generate_time_testcases():
	cases = [
		dateutil.parser.parse(e).time()
		for e in [
			'08:24:50.1414', '04:16:36.42', '01:00:24.0707',
			'01:00:24.289', '01:00:24.314589'
		]
	]
	for case in cases:
		yield str(case), (time, case)


def generate_timedelta_testcases():
	cases = [
		timedelta(days = e[0], seconds = e[1], microseconds = e[2])
		for e in [
			(1, 2, 3),
			(0, -4400002, 0),
			(0, 5000, 0),
			(0, 0, 45646),
			(0, 0, -65416540),
			(5454, 0, 0),
			(-6565, 0, 0),
		]
	]
	for case in cases:
		yield str(case), (timedelta, case)


def pytest_generate_tests(metafunc):
	'''
		Generates tests cases for simple deserialization and serialization,
		testcases are generated by functions with ```generate_``` prefix
	'''
	if metafunc.function.__name__ == 'test_serialization_pipeline':
		__GENERIC_TESTCASE_GENERATORS__ = [
			generate_set_testcases,
			generate_frozenset_testcases,
			generate_decimal_testcases,
			generate_datetime_testcases,
			generate_date_testcases,
			generate_time_testcases,
			generate_timedelta_testcases,
		]

		testcases = []
		for generator in __GENERIC_TESTCASE_GENERATORS__:
			testcases += list(generator())

		ids, params = zip(*testcases)
		metafunc.parametrize('cls, original_obj', params, ids = ids)
