/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.platform.database.oracle;

import java.io.StringWriter;
import java.sql.*;
import java.util.*;
import oracle.sql.*;
import org.eclipse.persistence.internal.helper.Helper;

/**
 * Used as a helper class for TIMESTAMP, TIMESTAMPTZ and TIMESTAMPLTZ in oracle9.
 */
public class TIMESTAMPHelper {

    /**
     * This conversion required the use of the literal string to get the same
     * functionality as the native SQL to_timestamp() approach.
     */
    public static TIMESTAMPTZ buildTIMESTAMPTZ(Calendar cal, Connection con, boolean shouldPrintCalendar) throws SQLException {
        //Bug5614674.  It used to be a driver bug and Helper.printCalendar(cal, false) was used to make it work.  It has been fixed in 11.  Separate the newer version from the old ones.
        if (shouldPrintCalendar) {
            return new TIMESTAMPTZ(con, Helper.printCalendar(cal, false), cal);
        } else {
            return new TIMESTAMPTZ(con, new Timestamp(cal.getTimeInMillis()), cal);
        }
    }

    /**
     * Build a calendar from TIMESTAMPTZWrapper.
     */
    public static Calendar buildCalendar(TIMESTAMPTZWrapper timestampTZ) throws SQLException{
        Timestamp ts = timestampTZ.getTimestamp();
        TimeZone tz = timestampTZ.getTimeZone();

        Calendar gCal;
        if(timestampTZ.isTimestampInGmt()) {
            gCal = Calendar.getInstance(tz);
            gCal.setTime(ts);
        } else {
            gCal = Calendar.getInstance();
            gCal.setTime(ts);
            gCal.getTimeZone().setID(tz.getID());
            gCal.getTimeZone().setRawOffset(tz.getRawOffset());
        }
        return gCal;
    }

   /**
    * Build a calendar from TIMESTAMPLTZWrapper.
    */
    public static Calendar buildCalendar(TIMESTAMPLTZWrapper timestampLTZ) throws SQLException{
        Calendar gCal;
        if (timestampLTZ.getZoneId() != null) {
            gCal = Calendar.getInstance(TimeZone.getTimeZone(timestampLTZ.getZoneId()));
        } else {
            gCal = Calendar.getInstance();
        }

        //This is the only way to set time in Calendar.  Passing Timestamp directly to the new
        //calendar does not work because the GMT time is wrong.
        if(timestampLTZ.isLtzTimestampInGmt()) {
            gCal.setTimeInMillis(timestampLTZ.getTimestamp().getTime());
        } else {
            Calendar localCalendar = Helper.allocateCalendar();
            localCalendar.setTime(timestampLTZ.getTimestamp());
            gCal.set(localCalendar.get(Calendar.YEAR), localCalendar.get(Calendar.MONTH), localCalendar.get(Calendar.DATE), localCalendar.get(Calendar.HOUR_OF_DAY), localCalendar.get(Calendar.MINUTE), localCalendar.get(Calendar.SECOND));
            Helper.releaseCalendar(localCalendar);
        }
        gCal.set(Calendar.MILLISECOND, timestampLTZ.getTimestamp().getNanos() / 1000000);

        return gCal;
    }

    /**
     * Build a calendar string based on the calendar fields.
     * If the daylight savings time should be printed and the zone is in daylight savings time,
     * print the short representation of daylight savings from the calendar's timezone data.
     */
    public static String printCalendar(final Calendar calendar) {
        if (calendar == null) {
            return "null";
        }
        final StringWriter writer = new StringWriter();
        writer.write(Helper.printCalendar(calendar, false));
        writer.write(" ");
        writer.write(calendar.getTimeZone().getID());
        // If we should print daylight savings and the zone is reported to be using daylight time,
        // write the short representation of the daylight time in the writer.
        if (shouldAppendDaylightTime(calendar)) {
            writer.write(" ");
            writer.write(calendar.getTimeZone().getDisplayName(true, TimeZone.SHORT));
        }
        return writer.toString();
    }

    /**
     * Return true if the calendar supports and is in daylight time
     * (according to its timezone), false otherwise
     */
    public static boolean shouldAppendDaylightTime(Calendar calendar) {
        if (calendar == null) {
            return false;
        }
        TimeZone zone = calendar.getTimeZone();
        return zone.useDaylightTime() && zone.inDaylightTime(calendar.getTime());
    }

    /**
     * Extract TimeZone from TIMESTAMPTZ.
     */
    public static TimeZone extractTimeZone(byte[] bytes) {
        String regionName = null;
        if ((bytes[11] & -128) != 0) {
            int regionCode = (bytes[11] & 127) << 6;
            regionCode += ((bytes[12] & 252) >> 2);
            regionName = new String(ZONEIDMAP.getRegion(regionCode));
        } else {
            int hourOffset = bytes[11] - 20;
            int minuteOffset = bytes[12] - 60;
            String offset = Helper.buildZeroPrefix(hourOffset, 2) + ":" + Helper.buildZeroPrefixWithoutSign(minuteOffset, 2);
            regionName = "GMT" + offset;
        }
        return TimeZone.getTimeZone(regionName);
    }
}
