#! /usr/bin/python -O

from eon_date import *
import unittest

class TestEonHelperFunctions(unittest.TestCase):

	#def setUp(self):
	#
	#def tearDown(self):
	#

	def test_weekday(self):

		self.assertEqual( weekday( 0 ), (6,'Saturday') )
		self.assertEqual( weekday(-7 ), (6,'Saturday') )

	def test_is_leap_year(self):

		years  = [ 1900,2000,2004, 2005]

		result = [False,True,True,False]
		is_leap = [ is_leap_year(yr) for yr in years ]
		self.assertEqual(is_leap, result)

		result = [True,True,True,False]
		is_leap = [ is_leap_year(yr,julian=True) for yr in years ]
		self.assertEqual(is_leap, result)

	def test_convert_month(self):

		self.assertEqual( convert_month( 2010,       4 ), (2010,4,'April') )
		self.assertEqual( convert_month( 2009,      16 ), (2010,4,'April') )
		self.assertEqual( convert_month( 2012,     -20 ), (2010,4,'April') )
		self.assertEqual( convert_month( 2010, 'April' ), (2010,4,'April') )
		self.assertRaises(EonError, convert_month, 2010, 'Arpil' )

	def test_days_in_month(self):

		self.assertEqual( days_in_month( 2010, 'February' ), 28 ) 
		self.assertEqual( days_in_month( 1900, 'February' ), 28 )
		self.assertEqual( days_in_month( 1900, 'February', julian=True ), 29 )
		self.assertRaises(EonError, days_in_month, 2010, 'Arpil' )

	def test_days_in_past_months(self):

		self.assertEqual( days_in_past_months( 2000, 'January' ), 0 )
		self.assertEqual( days_in_past_months( 2000, 'March'   ), 60 )
		self.assertEqual( days_in_past_months( 1900, 'March'   ), 59 )
		self.assertEqual( days_in_past_months( 1900, 'March', julian=True ), 60 )
		self.assertEqual( days_in_past_months( 1999, 'December'), 365-31 )

	def test_days_in_year(self):

		self.assertEqual( days_in_year( 2000 ), 366 )
		self.assertEqual( days_in_year( 2001 ), 365 )
		self.assertEqual( days_in_year( 1900 ), 365 )
		self.assertEqual( days_in_year( 1900, julian=True ), 366 )

	def test_days_in_past_years(self):

		self.assertEqual( days_in_past_years( 2000-2000 ),     0 )
		self.assertEqual( days_in_past_years( 2010-2000 ),  3653 )
		self.assertEqual( days_in_past_years( 1990-2000 ), -3652 )

	def test_fix_yr_month_day(self):

		self.assertEqual(fix_yr_month_day( 2002, -18, -51), (2000,4,'April',10))
		self.assertEqual(fix_yr_month_day( 1999, 15,  41), (2000,4,'April',10))

	def test_fix_yr_doy(self):

		self.assertEqual(fix_yr_doy( 2002, 101-365-366), (2000,101))
		self.assertEqual(fix_yr_doy( 1999, 101+365    ), (2000,101))

	def test_fix_dhms(self):

		self.assertEqual(fix_dhms( 1.5 , 0   , 0  , 0  ,     0			  ), (1,12, 0, 0,     0))
		self.assertEqual(fix_dhms( 1   , 0.5 , 0  , 0  ,     0			  ), (1, 0,30, 0,     0))
		self.assertEqual(fix_dhms( 1   , 0   , 0.5, 0  ,     0			  ), (1, 0, 0,30,     0))
		self.assertEqual(fix_dhms( 1   , 0   , 0  , 0  ,500000,exponent=6 ), (1, 0, 0, 0,500000))
		self.assertEqual(fix_dhms( 1.25, 0.25, 0.5, 0.5,250000,exponent=6 ), (1, 6,15,30,750000))
		self.assertEqual(fix_dhms( 1.25,-0.25,-0.5, 0.5,250000,exponent=6 ), (1, 5,44,30,750000))

	#def test_underestimate_years(self):

	#	pass

	#def test_underestimate_months(self):

	#	pass

	def test_year_doy(self):

		self.assertEqual( year_doy(    0 ) , (2000,  1) )
		self.assertEqual( year_doy(  366 ) , (2001,  1) )
		self.assertEqual( year_doy( -366 ) , (1998,365) )

	def test_days_since_2000(self):

		self.assertEqual( days_since_2000( 2000, 1   ),     0   )
		self.assertEqual( days_since_2000( 2000, 1.5 ),     0.5 )
		self.assertEqual( days_since_2000( 2010, 1   ),  3653   )
		self.assertEqual( days_since_2000( 1990, 1   ), -3652   )

		self.assertTrue ( is_integer(days_since_2000( 2000, 1   )) )
		self.assertTrue ( is_integer(days_since_2000( 2000, 1.0 )) )
		self.assertFalse( is_integer(days_since_2000( 2000, 1.5 )) )

	def test_doy2month_day(self):

		self.assertEqual( doy2month_day( 2000,  10    ), (2000,  1, 'January' , 10) )
		self.assertEqual( doy2month_day( 2001, -10-30 ), (2000, 11, 'November', 21) )

	def test_month_day2doy(self):

		self.assertEqual( month_day2doy( 2000,   1, 10 ), (2000, 10) )
		self.assertEqual( month_day2doy( 2001, -11, 32 ), (2000, 32) )

	def test_julian_to_gregorian(self):

		self.assertEqual( julian_to_gregorian( 1582, 1 ), (1582, 1+10))
		self.assertEqual( julian_to_gregorian( 2000, 1 ), (2000, 1+13))

	def test_gregorian_to_julian(self):

		self.assertEqual( gregorian_to_julian( 1582, 1+10 ), (1582, 1))
		self.assertEqual( gregorian_to_julian( 2000, 1+13 ), (2000, 1))

	def test_split_date_format(self):

		self.assertEqual( split_date_format( '20110825-130501.001', 'YYYYMMDD-hhmmss.ddd', exponent=6 ), ( 2011, 237, 8, 'August', 25, 13, 5, 1, 1000 ) )

	def test_split_date_regex(self):

		regex = "^equinix-chicago\.dirA\.(YYYY=\d{4})(MM=\d{2})(DD=\d{2})-(hh=\d{2})(mm=\d{2})(ss=\d{2})\.(TZ=UTC)\.anon\.(pcap|times|pcap\.stats)(\.gz)?$"
		ctime = 'equinix-chicago.dirA.20110825-130501.UTC.anon.pcap.gz'
		self.assertEqual( split_date_regex( ctime, regex ), ( 2011, 237, 8, 'August', 25, 13, 5, 1, 0 ) )


class TestEonFunctions(unittest.TestCase):

	def test_get_jepoch(self):

		self.assertEqual( eon_date(ctime='2000-01-01 12:00:00').get(attr='jepoch'), 2000 )
		self.assertEqual( eon_date(ctime='2010-01-01 00:00:00').get(attr='jepoch'), 2010 )

		self.assertEqual( eon_date(jepoch=2000).get(format='YYYY-MM-DD hh:mm:ss'), '2000-01-01 12:00:00' )
		self.assertEqual( eon_date(jepoch=2010).get(format='YYYY-MM-DD hh:mm:ss'), '2010-01-01 00:00:00' )

	def test_get_bepoch(self):

		self.assertEqual( eon_date(ctime='1899-12-31 19:31:28.12800').get(attr='bepoch'), 1900 )
		self.assertEqual( eon_date(ctime='2000/01/01 00:48:05.59584').get(attr='bepoch'), 2000 )

		self.assertEqual( eon_date(bepoch=1900).get(format='YYYY-MM-DD hh:mm:ss.ddddd'), '1899-12-31 19:31:28.12800' )
		self.assertEqual( eon_date(bepoch=2000).get(format='YYYY-MM-DD hh:mm:ss.ddddd'), '2000-01-01 00:48:05.59584' )

	def test_get_njd(self):

		self.assertEqual( eon_date(njd=0    ).get(format='YYYY-MM-DD hh:mm:ss'), '2000-01-01 12:00:00' )
		self.assertEqual( eon_date(njd=365.5).get(format='YYYY-MM-DD hh:mm:ss'), '2001-01-01 00:00:00' )

		self.assertEqual( eon_date('2000-01-01 12:00:00').get(attr='njd'),		0 )
		self.assertEqual( eon_date('2001-01-01 00:00:00').get(attr='njd'),  365.5 )

	def test_get_mjd(self):

		self.assertEqual( eon_date(mjd=		   0).get(format='YYYY-MM-DD hh:mm:ss'), '1858-11-16 12:00:00' )
		self.assertEqual( eon_date(mjd=g_NJD_MJD).get(format='YYYY-MM-DD hh:mm:ss'), '2000-01-01 12:00:00' )

		self.assertEqual( eon_date('1858-11-16 12:00:00').get(attr='mjd'), 		   0 )
		self.assertEqual( eon_date('2000-01-01 12:00:00').get(attr='mjd'), g_NJD_MJD )

	def test_get_jd(self):

		self.assertEqual( eon_date( jd=		  0).get(format='YYYY-MM-DD hh:mm:ss'), '-4713-11-24 12:00:00' )
		self.assertEqual( eon_date( jd=g_NJD_JD).get(format='YYYY-MM-DD hh:mm:ss'),  '2000-01-01 12:00:00' )

		self.assertEqual( eon_date( '-4713-11-24 12:00:00', format='YYYYY-MM-DD hh:mm:ss'	).get(attr='jd'), 		 0 )
		self.assertEqual( eon_date( '2000-01-01 12:00:00'									).get(attr='jd'), g_NJD_JD )

	def test_get_posix(self):

		self.assertEqual( eon_date( '1970-01-01 00:00:00' ).get(attr='posix'), 		0 )
		self.assertEqual( eon_date( '2000-01-01 00:00:00' ).get(attr='posix'), g_JD2000_POSIX*86400 )

		self.assertEqual( eon_date(posix=				    0).get(format='YYYY-MM-DD hh:mm:ss'), '1970-01-01 00:00:00' )
		self.assertEqual( eon_date(posix=g_JD2000_POSIX*86400).get(format='YYYY-MM-DD hh:mm:ss'), '2000-01-01 00:00:00' )

class TestEonTimeZoneFunctions(unittest.TestCase):

	def test_timezone(self):
		self.assertEqual( eon_date( '2012-12-31 22:22:22 PST', format='YYYY-MM-DD hh:mm:ss TZ').get(format='YYYY-MM-DD hh:mm:ss TZ',timezone='UTC'), '2013-01-01 06:22:22 +0000')
		self.assertEqual( eon_date( year=2012,month=12,day=31,hour=22,minute=22,second=22,timezone='PST' ).get(format='YYYY-MM-DD hh:mm:ss TZ',timezone='UTC'), '2013-01-01 06:22:22 +0000')
		self.assertEqual( eon_date( '2012-12-31 22:22:22 PST', format='YYYY-MM-DD hh:mm:ss TZ').get(attr='year' ,timezone='UTC'), 2013)
		self.assertEqual( eon_date( '2012-12-31 22:22:22 PST', format='YYYY-MM-DD hh:mm:ss TZ').get(attr='doy'  ,timezone='UTC'),    1)
		self.assertEqual( eon_date( '2012-12-31 22:22:22 PST', format='YYYY-MM-DD hh:mm:ss TZ').get(attr='month',timezone='UTC'), (1,'January'))

class TestEonOperators(unittest.TestCase):

	def test_addition(self):

		tdate  = eon_date ()
		tdelta = eon_delta()

		self.assertRaises( TypeError, testDatePlusDate, tdate, tdate  )
		self.assertEqual( (tdate +tdelta).__class__, tdate.__class__  )
		self.assertEqual( (tdelta+tdate ).__class__, tdate.__class__  )
		self.assertEqual( (tdelta+tdelta).__class__, tdelta.__class__ )

	def test_subtraction(self):

		tdate  = eon_date ()
		tdelta = eon_delta()

		self.assertEqual( (tdate-tdate  ).__class__, tdelta.__class__ )
		self.assertEqual( (tdate-tdelta ).__class__, tdate.__class__  )
		self.assertRaises( TypeError, testDeltaMinusDate, tdelta, tdate )
		self.assertEqual( (tdelta-tdelta).__class__, tdelta.__class__ )

	def test_negation(self):

		tdate  = eon_date ()
		tdelta = eon_delta()

		self.assertRaises( TypeError, testDateNegation, tdate )

# Wrappers for testing illegal operations on dates and deltas.

def testDeltaMinusDate( tt, uu):
	try:
		vv = tt-uu
	except TypeError:
		raise TypeError
	else:
		vv = 0

	return vv

def testDateNegation( tt ):
	try:
		vv = -tt
	except TypeError:
		raise TypeError
	else:
		vv = 0

	return vv

def testDatePlusDate( tt, uu):
	try:
		vv = tt+uu
	except TypeError:
		raise TypeError
	else:
		vv = 0

	return vv

if __name__ == '__main__':
    #unittest.main()

	suite = unittest.TestLoader().loadTestsFromTestCase(TestEonOperators)
	unittest.TextTestRunner(verbosity=2).run(suite)

	suite = unittest.TestLoader().loadTestsFromTestCase(TestEonHelperFunctions)
	unittest.TextTestRunner(verbosity=2).run(suite)

	suite = unittest.TestLoader().loadTestsFromTestCase(TestEonFunctions)
	unittest.TextTestRunner(verbosity=2).run(suite)

	suite = unittest.TestLoader().loadTestsFromTestCase(TestEonTimeZoneFunctions)
	unittest.TextTestRunner(verbosity=2).run(suite)

	from sys import exit
	exit(0)
