/*
 * Copyright (c) 1998, 2020 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:
//     dminsky - initial API and implementation
package org.eclipse.persistence.testing.tests.types;

import java.text.*;
import java.util.*;

import oracle.sql.*;

import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.descriptors.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.tools.schemaframework.*;
import org.eclipse.persistence.platform.database.oracle.*;

import org.eclipse.persistence.testing.framework.*;

/**
 * EL Bug 249500 - Daylight savings time is not printed in native SQL run against Oracle 9i and above
 * Regression test for validating that when a Calendar is inserted with native SQL enabled and binding
 * disabled, TZR TZD is printed when the Calendar reports that it is in DST (daylight savings time).
 * For other scenarios (DST not present, DST not used, DST not used anymore), only TZR is printed.
 *
 * Fix involves:
 * - Adding a method: TIMESTAMPHelper.shouldAppendDaylightTime() to determine if TZD data should be
 *   printed in addition to TZR data.
 * - Changed TIMESTAMPHelper.printCalendar() to check TIMESTAMPHelper.shouldAppendDaylightTime() and
 *   print the relevant data for the TZR TZD / TZR element(s).
 * - Changed Oracle9Platform.appendCalendar() to print TZR TZD or TZR depending on whether the
 *   Calendar instance passed is in DST or not.
 */
public class CalendarDaylightSavingsTest extends TestCase {

    // persistent fields
    private int testId;
    private Calendar calendar;

    // transient fields
    private QuerySQLTracker sqlTracker;
    private boolean oldBindingValue;
    private boolean oldNativeSqlValue;
    private CalendarDaylightSavingsTest result;

    // static test data
    private static List<Calendar> testCalendars;

    public CalendarDaylightSavingsTest() {
        super();
    }

    public CalendarDaylightSavingsTest(int testId, Calendar calendar) {
        super();
        setTestId(testId);
        setCalendar(calendar);
        setDescription(super.getDescription() + " -> " + formatCalendarAsString(calendar));
    }

    public Calendar getCalendar() {
        return calendar;
    }

    public void setCalendar(Calendar calendar) {
        this.calendar = calendar;
    }

    public int getTestId() {
        return testId;
    }

    public void setTestId(int testId) {
        this.testId = testId;
    }

    /**
     * Fancy mechanism for creating test Calendars for each TimeZone:
     * - 10 years in the past
     * - 10 years in the future
     * - this current date
     */
    public static List<Calendar> getTestCalendars() {
        if (testCalendars == null) {
            final String[] timeZones = new String[] {
                "US/Eastern",
                "US/Pacific",
                "EST",
                "PST",
                "GMT",
                "UTC",
                "America/New_York",
                "America/Los_Angeles",
                "Asia/Tokyo",
                "Europe/London",
                "Australia/Sydney", // uses DST
                "Australia/Brisbane", // used to use DST
                "Asia/Calcutta", // used to use DST
                "Asia/Bangkok", // never used DST
                "Asia/Riyadh", // never used DST
                "Asia/Jayapura", // never used DST
            };

            testCalendars = new ArrayList<Calendar>(timeZones.length * 4);
            for (int i = 0; i < timeZones.length; i++) {

                int[] months = new int[] { 0, -6 }; // - 6 months and current month
                for (int j = 0; j < months.length; j++) {

                    int[] years = new int[] { -10, 0, 10 }; // -10 years, current year and +10 years
                    for (int k = 0; k < years.length; k++) {
                        TimeZone timeZone = TimeZone.getTimeZone(timeZones[i]);
                        Calendar cal = Calendar.getInstance(timeZone);
                        cal.set(Calendar.DATE, 1);
                        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + months[j]);
                        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + years[k]);
                        cal.set(Calendar.HOUR, 1);
                        cal.set(Calendar.MINUTE, 0);
                        cal.set(Calendar.SECOND, 0);
                        cal.set(Calendar.MILLISECOND, 0);
                        cal.set(Calendar.AM_PM, Calendar.PM);
                        testCalendars.add(cal);
                    }
                }
            }
        }
        return testCalendars;
    }

    public String toString() {
        return "Test #: " + getTestId() + " -> " + formatCalendarAsString(this.calendar);
    }

    /**
     * Return a test instance for every item of test data
     */
    public static Vector testInstancesWithNoBindingAndNativeSql() {
        Vector tests = new Vector(getTestCalendars().size());
        for (int i = 0; i < getTestCalendars().size(); i++) {
            tests.add(new CalendarDaylightSavingsTest(i + 1, getTestCalendars().get(i)));
        }
        return tests;
    }

    public void setup() {
        if (!(getSession().getPlatform() instanceof Oracle9Platform)) {
            throw new TestWarningException("Test is only supported on Oracle9 platform and above, as TIMESTAMPTZ is used");
        }
        Oracle9Platform platform = (Oracle9Platform) getSession().getPlatform();

        this.oldBindingValue = platform.shouldBindAllParameters();
        this.oldNativeSqlValue = platform.usesNativeSQL();

        // parameter binding must be off and native SQL must be on
        platform.setShouldBindAllParameters(false);
        platform.setUsesNativeSQL(true);

        // delete myself if I exist because we need to perform an insert not an update
        try {
            UnitOfWork uow = getSession().acquireUnitOfWork();
            Object objectToDelete = uow.readObject(
                getClass(),
                new ExpressionBuilder().get("testId").equal(getTestId()));
            if (objectToDelete != null) {
                uow.deleteObject(objectToDelete);
                uow.commit();
            }
        } catch (Exception e) {
            throw new TestWarningException("Error whilst removing test object: " + getTestId(), e);
        }

        // create tracker object for query SQL
        sqlTracker = new QuerySQLTracker(getSession());
    }

    public void test() {
        // write myself out to the database
        UnitOfWork uow = getSession().acquireUnitOfWork();
        uow.registerObject(this);
        uow.commit();

        getSession().getIdentityMapAccessor().initializeIdentityMap(getClass());

        // read myself back from the database (bypassing the cache) with my id
        // this is to check that the object was correctly written to the database and that it exists
        ReadObjectQuery query = new ReadObjectQuery(CalendarDaylightSavingsTest.class);
        ExpressionBuilder builder = query.getExpressionBuilder();
        Expression expression = builder.get("testId").equal(getTestId());
        query.setSelectionCriteria(expression);
        query.setCacheUsage(query.DoNotCheckCache);

        // cache the result for later verification
        result = (CalendarDaylightSavingsTest)getSession().executeQuery(query);
    }

    public void verify() {
        final String TZR = "TZR";
        final String TZR_TZD = "TZR TZD";

        // add in check to determine if the SQL executed has the correct TZD and TZR fields in it
        List<String> statements = sqlTracker.getSqlStatements();
        if (statements.isEmpty()) {
            throw new TestErrorException("Test: " + getTestId() + " - No statements executed!");
        }


        if (this.result == null) {
            throw new TestErrorException("Result from database was null for test id: " + getTestId());
        }

        // get the SQL statement that was executed
        String statement = statements.get(0).toUpperCase();

        // if the TimeZone is in daylight time, we expect that the statement contains 'TZR TZD'
        // if the TimeZone is not in daylight time, we expect that the statement contains only 'TZR'
        TimeZone timeZone = calendar.getTimeZone();
        Date date = calendar.getTime();
        if (timeZone.inDaylightTime(date) && !statement.contains(TZR_TZD)) {
            throw new TestErrorException("Test: " + getTestId() + " - Expected sql statement string with: " + TZR_TZD + " -> " + statement);
        } else if (!timeZone.inDaylightTime(date) && !statement.contains(TZR)) {
            throw new TestErrorException("Test: " + getTestId() + " - Expected sql statement string with: " + TZR + " -> " + statement);
        }
    }

    public void reset() {
        // Compatibility for Oracle 9 and above is checked in the setup() method
        Oracle9Platform platform = (Oracle9Platform) getSession().getPlatform();
        platform.setUsesNativeSQL(this.oldNativeSqlValue);
        platform.setShouldBindAllParameters(this.oldBindingValue);
        // reset the SQL tracker
        if (sqlTracker != null) {
            sqlTracker.remove();
            sqlTracker = null;
        }
    }

    // Calendar pretty printing, not used for DB operations

    protected static String formatCalendarAsString(final Calendar cal) {
        final StringBuilder buffer = new StringBuilder();
        final TimeZone zone = cal.getTimeZone();
        final SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

        sdf.setCalendar(cal);
        sdf.setTimeZone(zone);
        buffer.append(sdf.format(cal.getTime()));

        buffer.append(" ");
        buffer.append(zone.getID());
        // SimpleDateFormat is not good enough to print exactly what I need to see from the TimeZone
        if (zone.inDaylightTime(cal.getTime())) {
            buffer.append(" ");
            buffer.append(zone.getDisplayName(true, TimeZone.SHORT));
        }
        return buffer.toString();
    }

    /*
    public static void main(String args[]) {
        List<Calendar> calendarz = getTestCalendars();
        Iterator<Calendar> i = calendarz.iterator();
        while (i.hasNext()) {
            Calendar cal = i.next();
            System.out.println(formatCalendarAsString(cal));
        }
    }*/

    // Descriptor and Table information

    private static RelationalDescriptor commonDescriptor() {
        RelationalDescriptor descriptor = new RelationalDescriptor();
    descriptor.setJavaClass(CalendarDaylightSavingsTest.class);
    descriptor.setTableName(tableDefinition().getName());
    descriptor.setPrimaryKeyFieldName("TEST_ID");
    descriptor.addDirectMapping("testId", "getTestId", "setTestId", "TEST_ID");
        return descriptor;
    }

    public static RelationalDescriptor descriptorWithAccessors() {
        RelationalDescriptor descriptor = commonDescriptor();
    descriptor.addDirectMapping("calendar", "getCalendar", "setCalendar", "TSTZ_DATA");
        return descriptor;
    }

    public static RelationalDescriptor descriptor() {
        RelationalDescriptor descriptor = commonDescriptor();
    descriptor.addDirectMapping("calendar", "TSTZ_DATA");
        return descriptor;
    }

    public static TableDefinition tableDefinition() {
        TableDefinition definition = new TableDefinition();
        definition.setName("CALENDARTOTSTZ_NATIVE");
        definition.addField("TEST_ID", Integer.class);
        definition.addField("TSTZ_DATA", TIMESTAMPTZ.class);
        return definition;
    }

}
