/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 *     
 *     14/05/2009 ailitchev - Bug 267929: Oracle 11.1.0.7: TIMESTAMP test '100 Years from now -> 2109-03-10 13:22:28.5 EST5EDT EDT' began to fail after Daylight Saving Time started
 *     Changed the test "100 Years from now" to "Last DST year" in both TIMESTAMPDirectToFieldTester and TIMESTAMPTypeConversionTester: 
 *     instead of hitting the current date 100 years ahead
 *     it now tests the current date on the latest year for which Daylight Saving Time is defined in Oracle db (by default lastDSTYear = 2020).
 *     The change was done because "100 Years from now" fails when run during DST (though passes outside of it).
 *     To figure out what is the latest year in your Oracle db for which DST defined,
 *     one of Oracle jdbc people suggested printing out the table which includes entries for each supported year
 *     (so the last entry in this table corresponds to the latest supported year).
 *     Here is the code that prints table with oracle jdbc 11.2.0.0.2 and later:
 *         String sTZ = conn.getSessionTimeZone();
 *         if (sTZ != null && ZONEIDMAP.isValidRegion(sTZ)) {
 *           System.out.println("Session TZ is " + sTZ);
 *           int regionID = ZONEIDMAP.getID(sTZ);
 *           System.out.println("Session TZ ID is " + regionID);
 *           TIMEZONETAB tzTab = TIMEZONETAB.getInstance(1);
 *           if (tzTab.checkID(regionID)) {
 *             tzTab.updateTable(conn, regionID);
 *           }
 *            tzTab.displayTable(regionID);
 *         }
 *     Here is the code that prints table with oracle jdbc 11.1.0.7 and earlier:
 *     (note that unlike 11.2 the user has to explicitly set time zone 
 *         conn.setSessionTimeZone(connTimeZone);
 *         String sTZ = conn.getSessionTimeZone();
 *         if (sTZ != null) {
 *           System.out.println("Session TZ is " + sTZ);
 *           int regionID = ZONEIDMAP.getID(sTZ);
 *           System.out.println("Session TZ ID is " + regionID);
 *           if (TIMEZONETAB.checkID(regionID)) {
 *               TIMEZONETAB.updateTable(conn, regionID);
 *           }
 *           TIMEZONETAB.displayTable(regionID);
 *         }
 ******************************************************************************/  
package org.eclipse.persistence.testing.tests.types;

import java.util.*;

import java.sql.*;

import oracle.jdbc.*;

import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.platform.database.oracle.TIMESTAMPHelper;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * This class is the super class of TIMESTAMP, TIMESTAMPTZ and TIMESTAMPLTZ specific
 * test cases.  The current subclasses are TIMESTAMPDirectToFieldTester and TIMESTAMPTypeConversionTester
 * that test Direct-to-Field or TypeConversion mapping.
 */
public abstract class TIMESTAMPTester extends TypeTester {

    public Timestamp tsToTS;
    public Timestamp tsToTSTZ;
    public Timestamp tsToTSLTZ;
    public Calendar calToTSTZ;
    public Calendar calToTSLTZ;
    public java.util.Date utilDateToTS;
    public java.util.Date utilDateToTSTZ;
    public java.util.Date utilDateToTSLTZ;
    public java.sql.Date dateToTS;
    public java.sql.Date dateToTSTZ;
    public java.sql.Date dateToTSLTZ;
    public Time timeToTS;
    public Time timeToTSTZ;
    public Time timeToTSLTZ;

    // This tsToTS will be stored in DATE field to make sure Timestamp -> DATE is backward compatible.
    public Timestamp tsToDate;
    // This Calendar will be stored in DATE field to make sure Calendar -> DATE is backward compatible.
    // ** So... why was this commmented out?  Is it backward compatible??
    //	public Calendar calToDate;
    public String sessionTimeZone;
    
    // isTimestampInGmt==true if driverVersion is 11.1.0.7 or later and
    // oracleConnection's property "oracle.jdbc.timestampTzInGmt" is set to "true".
    // The flag indicates whether TIMESTAMPTZ keeps its timestamp in GMT.
    public static boolean isTimestampInGmt;
    
    // true if driverVersion is 11.2.0.2 or later.
    public static boolean isLtzTimestampInGmt;

    // last year for which Daylight Saving Time is supported.  
    static int lastDSTYear = 2020;

    public TIMESTAMPTester() {
        super("NEW");
    }

    public TIMESTAMPTester(String nameOfTest, int year, int month, int date, int hrs, int min, int sec, int nano, 
                           int zoneMillis) {
        super(nameOfTest);

        calToTSTZ = Calendar.getInstance();
        calToTSTZ.getTimeZone().setRawOffset(zoneMillis);
        calToTSTZ.set(year, month, date, hrs, min, sec);
        calToTSTZ.set(Calendar.MILLISECOND, nano / 1000000);
        calToTSLTZ = calToTSTZ;
        buildUtilDates(calToTSTZ.getTime());
        buildTimestamps(utilDateToTS.getTime());
        buildDates(Helper.dateFromTimestamp(tsToTS));
        buildTimes(Helper.timeFromTimestamp(tsToTS));
        //		calToDate = c;
    }

    public TIMESTAMPTester(String nameOfTest, int year, int month, int date, int hrs, int min, int sec, int nano, 
                           String zoneId) {
        super(nameOfTest);

        /*		TimeZone tz = TimeZone.getDefault();
		tz.setID(zoneId);
		calToTSTZ = Calendar.getInstance(tz);*/
        calToTSTZ = Calendar.getInstance(TimeZone.getTimeZone(zoneId));
        calToTSTZ.set(year, month, date, hrs, min, sec);
        calToTSTZ.set(Calendar.MILLISECOND, nano / 1000000);
        calToTSLTZ = calToTSTZ;
        buildUtilDates(calToTSTZ.getTime());
        buildTimestamps(utilDateToTS.getTime());
        buildDates(Helper.dateFromTimestamp(tsToTS));
        buildTimes(Helper.timeFromTimestamp(tsToTS));
        //		calToDate = c;
    }

    public TIMESTAMPTester(String nameOfTest, Calendar c) {
        super(nameOfTest);
        calToTSTZ = c;
        calToTSLTZ = calToTSTZ;
        buildUtilDates(calToTSTZ.getTime());
        buildTimestamps(utilDateToTS.getTime());
        buildDates(Helper.dateFromTimestamp(tsToTS));
        buildTimes(Helper.timeFromTimestamp(tsToTS));
        //		calToDate = c;
    }

    public TIMESTAMPTester(String nameOfTest, long time) {
        super(nameOfTest);
        buildTimestamps(time);
        buildDates(Helper.dateFromTimestamp(tsToTS));
        buildTimes(Helper.timeFromTimestamp(tsToTS));
        buildUtilDates(new java.util.Date(time));
        calToTSTZ = Calendar.getInstance();
        calToTSTZ.setTime(utilDateToTS);
        calToTSLTZ = calToTSTZ;
        //		calToDate = c;
    }

    public void setSessionTimezone(String timeZone) {
        this.sessionTimeZone = timeZone;
    }
    
    protected void setup(Session session) {
        super.setup(session);
    }
    
    public void buildTimestamps(long time) {
        tsToTS = new Timestamp(time);
        tsToTSTZ = tsToTS;
        tsToTSLTZ = tsToTS;
        tsToDate = tsToTS;
    }

    public void buildUtilDates(java.util.Date date) {
        utilDateToTS = date;
        utilDateToTSTZ = date;
        utilDateToTSLTZ = date;
    }

    public void buildDates(java.sql.Date date) {
        dateToTS = date;
        dateToTSTZ = date;
        dateToTSLTZ = date;
    }

    public void buildTimes(Time time) {
        timeToTS = time;
        timeToTSTZ = time;
        timeToTSLTZ = time;
    }

    public Timestamp getTsToTS() {
        return tsToTS;
    }

    public Timestamp getTsToTSTZ() {
        return tsToTSTZ;
    }

    public Timestamp getTsToTSLTZ() {
        return tsToTSLTZ;
    }

    public Calendar getCalToTSTZ() {
        return calToTSTZ;
    }

    public Calendar getCalToTSLTZ() {
        return calToTSLTZ;
    }

    public Timestamp getTsToDate() {
        return tsToDate;
    }

    public java.util.Date getUtilDateToTS() {
        return utilDateToTS;
    }

    public java.util.Date getUtilDateToTSTZ() {
        return utilDateToTSTZ;
    }

    public java.util.Date getUtilDateToTSLTZ() {
        return utilDateToTSLTZ;
    }

    public java.sql.Date getDateToTS() {
        return dateToTS;
    }

    public java.sql.Date getDateToTSTZ() {
        return dateToTSTZ;
    }

    public java.sql.Date getDateToTSLTZ() {
        return dateToTSLTZ;
    }

    public Time getTimeToTS() {
        return timeToTS;
    }

    public Time getTimeToTSTZ() {
        return timeToTSTZ;
    }

    public Time getTimeToTSLTZ() {
        return timeToTSLTZ;
    }

    public void setTsToTS(java.sql.Timestamp aTimestamp) {
        tsToTS = aTimestamp;
    }

    public void setTsToTSTZ(java.sql.Timestamp aTimestamp) {
        tsToTSTZ = aTimestamp;
    }

    public void setTsToTSLTZ(java.sql.Timestamp aTimestamp) {
        tsToTSLTZ = aTimestamp;
    }

    public void setCalToTSTZ(Calendar calToTSTZ) {
        this.calToTSTZ = calToTSTZ;
    }

    public void setCalToTSLTZ(Calendar calToTSLTZ) {
        this.calToTSLTZ = calToTSLTZ;
    }

    public void setTsToDate(java.sql.Timestamp aTimestamp) {
        tsToDate = aTimestamp;
    }

    public void setUtilDateToTS(java.util.Date aDate) {
        utilDateToTS = aDate;
    }

    public void setUtilDateToTSTZ(java.util.Date aDate) {
        utilDateToTSTZ = aDate;
    }

    public void setUtilDateToTSLTZ(java.util.Date aDate) {
        utilDateToTSLTZ = aDate;
    }

    public void setDateToTS(java.sql.Date aDate) {
        dateToTS = aDate;
    }

    public void setDateToTSTZ(java.sql.Date aDate) {
        dateToTSTZ = aDate;
    }

    public void setDateToTSLTZ(java.sql.Date aDate) {
        dateToTSLTZ = aDate;
    }

    public void setTimeToTS(Time aDate) {
        timeToTS = aDate;
    }

    public void setTimeToTSTZ(Time aDate) {
        timeToTSTZ = aDate;
    }

    public void setTimeToTSLTZ(Time aDate) {
        timeToTSLTZ = aDate;
    }

    /*	public Calendar getCalToDate() {
		return calToDate;
	}

	public void setCalToDate(Calendar calToTSTZ) {
		this.calToDate = calToTSTZ;
	}*/

    public String toString() {
        return getTestName() + " -> " + TIMESTAMPHelper.printCalendar(calToTSTZ);
    }

    // Calendar's time zone is inserted into the db if the test runs either with binding or with native sql -
    // otherwise time zone is simply not present in the inserting sql and therefore
    // Calendar-to-TIMESTAMPTZ and Calendar-to-TIMESTAMPLTZ comparisons fail because
    // the objects are written into the db with connection's sessionTimeZone instead of the calendar's time zone. 
    boolean doesTestInsertCalendarTimeZone(WriteTypeObjectTest test) {
        return test.shouldBindAllParameters()==null || test.shouldBindAllParameters() || test.shouldUseNativeSQL();
    }

    // In case connection's session is not default and isTimestampInGmt==true
    // tsToTSTZ, utilDateToTSTZ and timeToTSTZ don't work.
    // Note that dateToTSTZ and calToTSTZ work.
    // The reason is Oracle jdbc bug 8206596:
    // Timestamp for 5pm in default zone (say NewYork) written into TIMESTAMPTZ using setObject
    // is inserted into the db as 5pm LosAngeles (in case it's set as a session time zone).
    // That happens with both 11.1.0.6 and 11.1.0.7 ojdbc versions.
    // When the result is read back 11.1.0.7 driver (in case timestampTzInGmt prop. is set to true - which is default setting)
    // correctly reads 5pm LA - and fails comparison with 5pm NY,
    // however version 11.0.0.6 (and 11.1.0.7 with timestampTzInGmt prop. set to false)
    // incorrectly reads back 5pm in default zone - so the inserted and the read back objects are equal.
    // Note that this incorrect reading happens only in case the target Java type is Timestamp (util.Date, Time),
    // Eclipselink corrects the result in case the target type is Calendar.
    boolean doesTimestampTZWork() {
        return TimeZone.getDefault().getID().equals(this.sessionTimeZone) || !isTimestampInGmt; 
    }
    
    // see the previous comment:
    // it used to work - due to even number of errors - in 11.1.0.7,
    // but no longer works in 11.2.0.2.
    // Again, as in TIMESTAMPTZ field case,
    // writing Timestamp, or Time, or Date, or util.Date while sessionTimeZone is not equal to default time zone
    // results in combining of a time in default time zone and session time zone.
    // Therefore 5p.m. in default zone America/New_York written through America/Los_Angeles sessionTimeZone
    // is recorded in the db. as 5p.m. America/Los_Angeles.
    boolean doesTimestampLTZWork() {
        return TimeZone.getDefault().getID().equals(this.sessionTimeZone) || !isLtzTimestampInGmt; 
    }
    
    protected void test(WriteTypeObjectTest testCase) {
        try {
            if(this.sessionTimeZone != null) {
                getConnection((DatabaseSession)testCase.getSession()).setSessionTimeZone(this.sessionTimeZone);
            }
        } catch (Exception exception) {
            throw new TestProblemException("Error setting timezone on connection.", exception);
        }
        super.test(testCase);
    }

    protected void verify(WriteTypeObjectTest testCase) throws TestException {
        try {
            super.verify(testCase);
        } catch (TestException e) {
            TIMESTAMPTester fromDatabase = (TIMESTAMPTester)testCase.getObjectFromDatabase();
            if (fromDatabase == null) {
                throw new TestErrorException("Value from database is null: " + e);
            }

            String errorMsg = "";
            if (!tsToTS.equals(fromDatabase.getTsToTS())) {
                errorMsg += "The tsToTS should be: " + tsToTS + ", but was read as: " + fromDatabase.getTsToTS() + "\n";
            }
            if(doesTimestampTZWork()) {
                if (!tsToTSTZ.equals(fromDatabase.getTsToTSTZ())) {
                    errorMsg += "The tsToTSTZ should be: " + tsToTSTZ + ", but was read as: " + fromDatabase.getTsToTSTZ() + "\n";
                }
            }
            if(doesTimestampLTZWork()) {
                if (!tsToTSLTZ.equals(fromDatabase.getTsToTSLTZ())) {
                    errorMsg += "The tsToTSLTZ should be: " + tsToTSLTZ + ", but was read as: " + fromDatabase.getTsToTSLTZ() + "\n";
                }
            }
            if (!utilDateToTS.equals(fromDatabase.getUtilDateToTS())) {
                errorMsg += "The utilDateToTS should be: " + utilDateToTS + ", but was read as: " + fromDatabase.getUtilDateToTS() + "\n";
            }
            if(doesTimestampTZWork()) {
                if (!utilDateToTSTZ.equals(fromDatabase.getUtilDateToTSTZ())) {
                    errorMsg += "The utilDateToTSTZ should be: " + utilDateToTSTZ + ", but was read as: " + fromDatabase.getUtilDateToTSTZ() + "\n";
                }
            }
            if(doesTimestampLTZWork()) {
                if (!utilDateToTSLTZ.equals(fromDatabase.getUtilDateToTSLTZ())) {
                    errorMsg += "The utilDateToTSLTZ should be: " + utilDateToTSLTZ + ", but was read as: " + fromDatabase.getUtilDateToTSLTZ() + "\n";
                }
            }
            if (!dateToTS.equals(fromDatabase.getDateToTS())) {
                errorMsg += "The dateToTS should be: " + dateToTS + ", but was read as: " + fromDatabase.getDateToTS() + "\n";
            }
            if (!dateToTSTZ.equals(fromDatabase.getDateToTSTZ())) {
                errorMsg += "The dateToTSTZ should be: " + dateToTSTZ + ", but was read as: " + fromDatabase.getDateToTSTZ() + "\n";
            }
            if (!dateToTSLTZ.equals(fromDatabase.getDateToTSLTZ())) {
                errorMsg += "The dateToTSLTZ should be: " + dateToTSLTZ + ", but was read as: " + fromDatabase.getDateToTSLTZ() + "\n";
            }
            if (!timeToTS.equals(fromDatabase.getTimeToTS())) {
                errorMsg += "The timeToTS should be: " + timeToTS + ", but was read as: " + fromDatabase.getTimeToTS() + "\n";
            }
            if(doesTimestampTZWork()) {
                if (!timeToTSTZ.equals(fromDatabase.getTimeToTSTZ())) {
                    errorMsg += "The timeToTSTZ should be: " + timeToTSTZ + ", but was read as: " + fromDatabase.getTimeToTSTZ() + "\n";
                }
            }
            if(doesTimestampLTZWork()) {
                if (!timeToTSLTZ.equals(fromDatabase.getTimeToTSLTZ())) {
                    errorMsg += "The timeToTSLTZ should be: " + timeToTSLTZ + ", but was read as: " + fromDatabase.getTimeToTSLTZ() + "\n";
                }
            }

            String originalCal = TIMESTAMPHelper.printCalendar(calToTSLTZ);
            String dbCal = TIMESTAMPHelper.printCalendar(fromDatabase.getCalToTSLTZ());
            //calToTSLTZ from database should have the sessionTimeZone
            if (sessionTimeZone!=null && !fromDatabase.getCalToTSLTZ().getTimeZone().getID().trim().equals(sessionTimeZone.trim())) {
                errorMsg += "The sessionTimeZone should be: " + sessionTimeZone + ", but was read as: " + 
                                             fromDatabase.getCalToTSLTZ().getTimeZone().getID();
            }

            //Calendar-to-TIMESTAMPLTZ does not work if calendar's time stamp is not inserted into the db.
            if (doesTestInsertCalendarTimeZone(testCase)) {
                // 0 if and only if the two calendars refer to the same time
                int compareCalToTSLTZ = calToTSLTZ.compareTo(fromDatabase.getCalToTSLTZ());
                if(compareCalToTSLTZ != 0) {
                    errorMsg += "calToTSLTZ.compareTo(fromDatabase.getCalToTSLTZ()) == " + compareCalToTSLTZ + "\n"; 
                    errorMsg += "\t    original calToTSLTZ = " + TIMESTAMPHelper.printCalendar(calToTSLTZ) + "\n";
                    errorMsg += "\tfromDatabase.calToTSLTZ = " + TIMESTAMPHelper.printCalendar(fromDatabase.getCalToTSLTZ())  + "\n";
                    errorMsg += "\t    original calToTSLTZ = " + calToTSLTZ + "\n";
                    errorMsg += "\tfromDatabase.calToTSLTZ = " + fromDatabase.getCalToTSLTZ()  + "\n";
                }
            }

            //Calendar-to-TIMESTAMPTZ does not work if calendar's time stamp is not inserted into the db.
            if (doesTestInsertCalendarTimeZone(testCase)) {
                originalCal = TIMESTAMPHelper.printCalendar(calToTSTZ);
                dbCal = TIMESTAMPHelper.printCalendar(fromDatabase.getCalToTSTZ());
                // indicates whether the original and read back from the db calendars are equal
                boolean areEqual = true;
                if(this.isTimestampInGmt) {
                    // 0 if and only if the two calendars refer to the same time
                    int compareCalToTSTZ = calToTSTZ.compareTo(fromDatabase.getCalToTSTZ());
                    boolean timeZonesEqual = calToTSTZ.getTimeZone().equals(fromDatabase.getCalToTSTZ().getTimeZone());
                    if(compareCalToTSTZ != 0 || !timeZonesEqual) {
                        areEqual = false;
                        if(compareCalToTSTZ != 0) {
                            errorMsg += "calToTSTZ.compareTo(fromDatabase.getCalToTSTZ()) == " + compareCalToTSTZ + "\n";
                        } else {
                            errorMsg += "time zones are not equal: \n";
                        }
                    }
                } else {
                    if (!originalCal.equals(dbCal)) {
                        areEqual = false;
                        errorMsg += "!originalCal.equals(dbCal)\n";
                    }
                }
                if(!areEqual) {
                    errorMsg += "\t    original calToTSTZ = " + originalCal + "\n";
                    errorMsg += "\tfromDatabase.calToTSTZ = " + dbCal  + "\n";
                    errorMsg += "\t    original calToTSTZ = " + calToTSTZ + "\n";
                    errorMsg += "\tfromDatabase.calToTSTZ = " + fromDatabase.getCalToTSTZ()  + "\n";
                }
            }

            //DATE field does not store milliseconds.  Need to compare the original tsToTS without milliseconds with
            //the one from the database.
            Timestamp objectTimeInCache = getTsToDate();
            int originalTS = objectTimeInCache.getNanos();
            //Some original tsToDate without milliseconds fell through the Calendar check and need to excluded from
            //the following check.
            //			if (originalTS != 0) {

            // TsToDate always looses nanos, so do not throw an error if the ts match without the nanos.
            objectTimeInCache.setNanos(0);
            Timestamp objectTimeInDB = fromDatabase.getTsToDate();
            if (objectTimeInCache.equals(objectTimeInDB)) {
                if (originalTS != objectTimeInDB.getNanos()) {
                    // Nanos don't match, ok, as everything else has been checked, assume this was the reason for the error.
                    if(errorMsg.length() == 0) {
                        return;
                    }
                } else if (!calToTSLTZ.equals(fromDatabase.getCalToTSLTZ())) {
                    // This seems to be ok, as the timezones are not suppose to come back the same??
                    // So ok, as everything else has been checked, assume this was the reason for the error.
                    if(errorMsg.length() == 0) {
                        return;
                    }
                }
            } else {
                objectTimeInCache.setNanos(originalTS);
                errorMsg += "The tsToDate should be: " + objectTimeInCache + " but were read back as: " + 
                                             objectTimeInDB;
            }
            if(errorMsg.length() > 0) {
                throw new TestErrorException("\n"+errorMsg, e);
            } else {
                throw e;
            }
        }
    }

    private OracleConnection getConnection(DatabaseSession session) {
        Connection connection = ((AbstractSession)session).getAccessor().getConnection();
        return (OracleConnection)session.getServerPlatform().unwrapConnection(connection);
    }
}
