/*
 * Copyright (c) 1998, 2021 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// 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;
    }

    @Override
    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;
    }

    @Override
    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);
    }

    @Override
    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);
    }
}
