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

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

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

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

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

}
