import os


import os,sys, test_util, time
from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods import Database

from Ft.Ods import DateFactory, TimeFactory, TimeStampFactory

from Ft.Ods import Date, Interval, TimeImp, TimeStamp


DBNAME=os.environ.get("ODS_TEST_DB","ods:test")


odl_string = '''
module Test {
  class Foo
  {
    attribute date d;
    attribute interval i;
    attribute time t;
    attribute timestamp ts;
  };
};

'''

def Test(tester):
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')
        pass
def _Test(tester):

    tester.startGroup("Date, Interval, time, and timestamp complex types %s Driver" % tester.test_data['driver'])

    tester.startTest("Date Factory")

    df=DateFactory
    d=df.calendar_date(2001,4,1)
    tester.compare(2001,d.year())
    tester.compare(4,d.month())
    tester.compare(1,d.day())
    tester.compare(1,df.is_leap_year(2004))
    tester.compare(0,df.is_leap_year(2001))
    tester.compare(0,df.is_leap_year(2000))
    tester.compare(1,df.is_valid_date(2000,01,01))
    tester.compare(0,df.is_valid_date(2001,02,41))
    tester.compare(366,df.days_in_year(2004))
    tester.compare(365,df.days_in_year(2001))
    tester.compare(28,df.days_in_month(2001,Date.Date.Month.February))
    tester.compare(29,df.days_in_month(2004,Date.Date.Month.February))
    tester.compare(31,df.days_in_month(2001,Date.Date.Month.January))

    d=df.julian_date(2001,3)
    tester.compare(2001,d.year())
    tester.compare(1,d.month())
    tester.compare(3,d.day())

    d=df.julian_date(2001,32)
    tester.compare(2001,d.year())
    tester.compare(2,d.month())
    tester.compare(1,d.day())


    tester.testDone()

    tester.startTest("Date")
    d=df.calendar_date(2001,4,1)
    #41 yrs since EPOCH
    #leap years are 60,64,68,72,76,80,84,88,92,96
    #Plus 3 months
    days = 365 * 41 + 10 + 31 + 28 + 31
    secs = days * 3600*24
    tester.compare(secs,d.value)


    tester.compare(2001,d.year())
    tester.compare(4,d.month())
    tester.compare(1,d.day())
    tester.compare(31+28+31+1,d.day_of_year())
    tester.compare(Date.Date.Month.April,d.month_of_year())
    tester.compare(Date.Date.Weekday.Sunday,d.day_of_week())
    tester.compare(0,d.is_leap_year())

    d2 = df.calendar_date(2001,4,1)
    d3 = df.calendar_date(2001,3,31)
    d4 = df.calendar_date(2001,4,2)

    tester.compare(1,d.is_equal(d2))
    tester.compare(0,d.is_equal(d3))
    tester.compare(0,d.is_equal(d4))

    tester.compare(0,d.is_greater(d2))
    tester.compare(1,d.is_greater(d3))
    tester.compare(0,d.is_greater(d4))

    tester.compare(1,d.is_greater_or_equal(d2))
    tester.compare(1,d.is_greater_or_equal(d3))
    tester.compare(0,d.is_greater_or_equal(d4))

    tester.compare(0,d.is_less(d2))
    tester.compare(0,d.is_less(d3))
    tester.compare(1,d.is_less(d4))

    tester.compare(1,d.is_less_or_equal(d2))
    tester.compare(0,d.is_less_or_equal(d3))
    tester.compare(1,d.is_less_or_equal(d4))


    tester.compare(1,d.is_between(d3,d4))
    tester.compare(1,d.is_between(d2,d4))
    tester.compare(0,d.is_between(d2,d3))

    nw = d.next(Date.Date.Weekday.Wednesday)
    tester.compare(2001,nw.year())
    tester.compare(4,nw.month())
    tester.compare(4,nw.day())

    lw = d.previous(Date.Date.Weekday.Wednesday)
    tester.compare(2001,lw.year())
    tester.compare(3,lw.month())
    tester.compare(28,lw.day())

    nd = d.add_days(1)
    tester.compare(2001,nd.year())
    tester.compare(4,nd.month())
    tester.compare(2,nd.day())

    nd = d.subtract_days(1)
    tester.compare(2001,nd.year())
    tester.compare(3,nd.month())
    tester.compare(31,nd.day())


    tester.compare(1,d.subtract_date(d3))


    tester.testDone()


    tester.startTest("Interval")

    i = Interval.Interval(None,30.12)
    tester.compare(120,i.millisecond())
    tester.compare(30,i.second())
    tester.compare(0,i.minute())
    tester.compare(0,i.hour())
    tester.compare(0,i.day())

    i = Interval.Interval(None,62.12)
    tester.compare(120,i.millisecond())
    tester.compare(2,i.second())
    tester.compare(1,i.minute())
    tester.compare(0,i.hour())
    tester.compare(0,i.day())

    i = Interval.Interval(None,3662.12)
    tester.compare(120,i.millisecond())
    tester.compare(2,i.second())
    tester.compare(1,i.minute())
    tester.compare(1,i.hour())
    tester.compare(0,i.day())

    i = Interval.Interval(None,3662.12+86400)
    tester.compare(120,i.millisecond())
    tester.compare(2,i.second())
    tester.compare(1,i.minute())
    tester.compare(1,i.hour())
    tester.compare(1,i.day())

    i = Interval.Interval(None,3662.12+(86400*100))
    tester.compare(120,i.millisecond())
    tester.compare(2,i.second())
    tester.compare(1,i.minute())
    tester.compare(1,i.hour())
    tester.compare(100,i.day())

    i1 = Interval.Interval(None,30)
    i2 = Interval.Interval(None,15)

    i3 = i2.plus(i1)
    tester.compare(0,i3.millisecond())
    tester.compare(45,i3.second())
    tester.compare(0,i3.minute())
    tester.compare(0,i3.hour())
    tester.compare(0,i3.day())
    
    i3 = i1.minus(i2)
    tester.compare(0,i3.millisecond())
    tester.compare(15,i3.second())
    tester.compare(0,i3.minute())
    tester.compare(0,i3.hour())
    tester.compare(0,i3.day())

    i3 = i2.product(2)
    tester.compare(0,i3.millisecond())
    tester.compare(30,i3.second())
    tester.compare(0,i3.minute())
    tester.compare(0,i3.hour())
    tester.compare(0,i3.day())

    i3 = i1.quotient(2)
    tester.compare(0,i3.millisecond())
    tester.compare(15,i3.second())
    tester.compare(0,i3.minute())
    tester.compare(0,i3.hour())
    tester.compare(0,i3.day())

    i3 = Interval.Interval(None,45)

    tester.compare(1,i1.is_equal(i1))
    tester.compare(0,i1.is_equal(i2))
    tester.compare(0,i1.is_equal(i3))

    tester.compare(0,i1.is_greater(i1))
    tester.compare(1,i1.is_greater(i2))
    tester.compare(0,i1.is_greater(i3))

    tester.compare(1,i1.is_greater_or_equal(i1))
    tester.compare(1,i1.is_greater_or_equal(i2))
    tester.compare(0,i1.is_greater_or_equal(i3))

    tester.compare(0,i1.is_less(i1))
    tester.compare(0,i1.is_less(i2))
    tester.compare(1,i1.is_less(i3))

    tester.compare(1,i1.is_less_or_equal(i1))
    tester.compare(0,i1.is_less_or_equal(i2))
    tester.compare(1,i1.is_less_or_equal(i3))

    tester.testDone()

    tester.startTest("Time Factory")

    tf = TimeFactory

    tester.compare(0,tf.default_time_zone())
    tf.set_default_time_zone(TimeImp.TimeImp.GMT)
    tester.compare(0,tf.default_time_zone())
    tf.set_default_time_zone(TimeImp.TimeImp.USmountain)
    tester.compare(time.timezone/-3600,tf.time_zone())
    #Test Time creation on when TimeImp is tested
    tester.testDone()

    tester.startTest("Time")

    t = tf.from_hmsm(10,10,10,10)
    tester.compare(10,t.hour())
    tester.compare(10,t.minute())
    tester.compare(10,t.second())
    tester.compare(10,t.millisecond())
    tester.compare(0,t.tz_hour())
    tester.compare(0,t.tz_minute())

    t1 = tf.from_hmsm(10,10,10,10)
    t2 = tf.from_hmsm(10,10,11,10)
    t3 = tf.from_hmsm(10,10,9,10)

    tester.compare(1,t1.is_equal(t1))
    tester.compare(0,t1.is_equal(t2))
    tester.compare(0,t1.is_equal(t3))

    tester.compare(0,t1.is_greater(t1))
    tester.compare(0,t1.is_greater(t2))
    tester.compare(1,t1.is_greater(t3))

    tester.compare(1,t1.is_greater_or_equal(t1))
    tester.compare(0,t1.is_greater_or_equal(t2))
    tester.compare(1,t1.is_greater_or_equal(t3))

    tester.compare(0,t1.is_less(t1))
    tester.compare(1,t1.is_less(t2))
    tester.compare(0,t1.is_less(t3))

    tester.compare(1,t1.is_less_or_equal(t1))
    tester.compare(1,t1.is_less_or_equal(t2))
    tester.compare(0,t1.is_less_or_equal(t3))

    tester.compare(1,t1.is_between(t3,t2))
    tester.compare(0,t1.is_between(t2,t3))

    t4 = t1.add_interval(Interval.Interval(None,1))
    tester.compare(10,t4.hour())
    tester.compare(10,t4.minute())
    tester.compare(11,t4.second())
    tester.compare(10,t4.millisecond())

    t4 = t1.subtract_interval(Interval.Interval(None,1))
    tester.compare(10,t4.hour())
    tester.compare(10,t4.minute())
    tester.compare(9,t4.second())
    tester.compare(10,t4.millisecond())

    i = t2.subtract_time(t1)
    tester.compare(0,i.hour())
    tester.compare(0,i.minute())
    tester.compare(1,i.second())
    tester.compare(0,i.millisecond())

    t = time.gmtime(time.time())

    #Testing current takes too much thought
    t1 = tf.current()

    t1 = tf.from_hmsmtz(10,10,10,10,-3,0)
    tester.compare(13,t1.hour())
    tester.compare(10,t1.minute())
    tester.compare(10,t1.second())
    tester.compare(10,t1.millisecond())
    tester.compare(-3,t1.tz_hour())
    tester.compare(0,t1.tz_minute())

    tester.testDone()


    tester.startTest("TimeStamp")

    tsf = TimeStampFactory
    
    ts = tsf.create(df.calendar_date(2001,04,01),tf.from_hmsm(10,10,10,10))

    tester.compare(2001,ts.year())
    tester.compare(4,ts.month())
    tester.compare(1,ts.day())
    tester.compare(10,ts.hour())
    tester.compare(10,ts.minute())
    tester.compare(10,ts.second())
    tester.compare(10,ts.millisecond())
    tester.compare(0,ts.tz_hour())
    tester.compare(0,ts.tz_minute())


    ts1 = tsf.create(df.calendar_date(2001,04,01),tf.from_hmsm(10,10,10,10))
    ts2 = tsf.create(df.calendar_date(2001,05,01),tf.from_hmsm(10,10,10,10))
    ts3 = tsf.create(df.calendar_date(2001,04,01),tf.from_hmsm(9,10,10,10))

    ts4  = ts.plus(Interval.Interval(None,1))
    tester.compare(2001,ts4.year())
    tester.compare(4,ts4.month())
    tester.compare(1,ts4.day())
    tester.compare(10,ts4.hour())
    tester.compare(10,ts4.minute())
    tester.compare(11,ts4.second())
    tester.compare(10,ts4.millisecond())
    tester.compare(0,ts4.tz_hour())
    tester.compare(0,ts4.tz_minute())
    ts4  = ts.minus(Interval.Interval(None,1))
    tester.compare(2001,ts4.year())
    tester.compare(4,ts4.month())
    tester.compare(1,ts4.day())
    tester.compare(10,ts4.hour())
    tester.compare(10,ts4.minute())
    tester.compare(9,ts4.second())
    tester.compare(10,ts4.millisecond())
    tester.compare(0,ts4.tz_hour())
    tester.compare(0,ts4.tz_minute())
    


    tester.compare(1,ts1.is_equal(ts1))
    tester.compare(0,ts1.is_equal(ts2))
    tester.compare(0,ts1.is_equal(ts3))

    tester.compare(0,ts1.is_greater(ts1))
    tester.compare(0,ts1.is_greater(ts2))
    tester.compare(1,ts1.is_greater(ts3))

    tester.compare(1,ts1.is_greater_or_equal(ts1))
    tester.compare(0,ts1.is_greater_or_equal(ts2))
    tester.compare(1,ts1.is_greater_or_equal(ts3))

    tester.compare(0,ts1.is_less(ts1))
    tester.compare(1,ts1.is_less(ts2))
    tester.compare(0,ts1.is_less(ts3))

    tester.compare(1,ts1.is_less_or_equal(ts1))
    tester.compare(1,ts1.is_less_or_equal(ts2))
    tester.compare(0,ts1.is_less_or_equal(ts3))

    tester.compare(1,ts1.is_between(ts3,ts2))
    tester.compare(0,ts1.is_between(ts2,ts3))

    tester.testDone()

    test_util.DbInit(DBNAME,odl_string)

    tester.startTest('Testing Generated syntax')
    try:
        from Test import Foo
        reload(Foo)
    except:
        tester.error('Error in syntax', 1)


    tester.testDone()

    
    db = Database.Database()
    db.open(DBNAME)

    try:
        tx = db.new()
        tx.begin()
        tester.startTest("Test Creation of Time Values")
        f = Foo.new(db)
        if db.lookup('TestFoo'):
            db.unbind("TestFoo")
        db.bind(f,"TestFoo")

        tester.compare(1,isinstance(f.d,Date.Date))
        tester.compare(1,isinstance(f.i,Interval.Interval))
        tester.compare(1,isinstance(f.t,TimeImp.TimeImp))
        tester.compare(1,isinstance(f.ts,TimeStamp.TimeStamp))


        #Set the values
        f.d = df.calendar_date(2001,04,01)
        f.i = Interval.Interval(None,15)
        f.t = tf.from_hmsm(10,10,10,10)
        f.ts = tsf.create(df.calendar_date(2001,05,01),tf.from_hmsm(12,10,10,10))

        tx.commit()
        tester.testDone()

        tester.startTest("Load and Modify the values")
        tx = db.new()
        tx.begin()
        f = db.lookup("TestFoo")

        tester.compare(1,isinstance(f.d,Date.Date))
        tester.compare(1,isinstance(f.i,Interval.Interval))
        tester.compare(1,isinstance(f.t,TimeImp.TimeImp))
        tester.compare(1,isinstance(f.ts,TimeStamp.TimeStamp))

        tester.compare(2001,f.d.year())
        tester.compare(4,f.d.month())
        tester.compare(1,f.d.day())

        tester.compare(0,f.i.millisecond())
        tester.compare(15,f.i.second())
        tester.compare(0,f.i.minute())
        tester.compare(0,f.i.hour())
        tester.compare(0,f.i.day())

        tester.compare(10,f.t.hour())
        tester.compare(10,f.t.minute())
        tester.compare(10,f.t.second())
        tester.compare(10,f.t.millisecond())
        tester.compare(0,f.t.tz_hour())
        tester.compare(0,f.t.tz_minute())


        tester.compare(2001,f.ts.year())
        tester.compare(5,f.ts.month())
        tester.compare(1,f.ts.day())
        tester.compare(12,f.ts.hour())
        tester.compare(10,f.ts.minute())
        tester.compare(10,f.ts.second())
        tester.compare(10,f.ts.millisecond())
        tester.compare(0,f.ts.tz_hour())
        tester.compare(0,f.ts.tz_minute())


        #Set the values
        f.d = df.calendar_date(2001,06,01)
        f.i = Interval.Interval(None,30)
        f.t = tf.from_hmsm(10,10,15,10)
        f.ts = tsf.create(df.calendar_date(2001,02,02),tf.from_hmsm(12,10,0,10))


        tx.commit()
        tester.testDone()

        tester.startTest("Check modification")

        tx = db.new()
        tx.begin()
        f = db.lookup("TestFoo")

        tester.compare(1,isinstance(f.d,Date.Date))
        tester.compare(1,isinstance(f.i,Interval.Interval))
        tester.compare(1,isinstance(f.t,TimeImp.TimeImp))
        tester.compare(1,isinstance(f.ts,TimeStamp.TimeStamp))

        tester.compare(2001,f.d.year())
        tester.compare(6,f.d.month())
        tester.compare(1,f.d.day())

        tester.compare(0,f.i.millisecond())
        tester.compare(30,f.i.second())
        tester.compare(0,f.i.minute())
        tester.compare(0,f.i.hour())
        tester.compare(0,f.i.day())

        tester.compare(10,f.t.hour())
        tester.compare(10,f.t.minute())
        tester.compare(15,f.t.second())
        tester.compare(10,f.t.millisecond())
        tester.compare(0,f.t.tz_hour())
        tester.compare(0,f.t.tz_minute())


        tester.compare(2001,f.ts.year())
        tester.compare(2,f.ts.month())
        tester.compare(2,f.ts.day())
        tester.compare(12,f.ts.hour())
        tester.compare(10,f.ts.minute())
        tester.compare(0,f.ts.second())
        tester.compare(10,f.ts.millisecond())
        tester.compare(0,f.ts.tz_hour())
        tester.compare(0,f.ts.tz_minute())

        tx.commit()

        tester.testDone()
    finally:
        db.close()

    tester.groupDone()


