/*
 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8347841
 * @summary test Time Zone Boundary
 * @run junit TimeZoneBoundaryTest
 */

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.fail;

/**
 * A test which discovers the boundaries of DST programmatically and verifies
 * that they are correct.
 */
public class TimeZoneBoundaryTest
{
    static final int ONE_SECOND = 1000;
    static final int ONE_MINUTE = 60*ONE_SECOND;
    static final int ONE_HOUR = 60*ONE_MINUTE;
    static final long ONE_DAY = 24*ONE_HOUR;
    static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
    static final long SIX_MONTHS = ONE_YEAR / 2;

    static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};

    // These values are empirically determined to be correct
    static final long PST_1997_BEG  = 860320800000L;
    static final long PST_1997_END  = 877856400000L;

    // Minimum interval for binary searches in ms; should be no larger
    // than 1000.
    static final long INTERVAL = 10; // Milliseconds

    static final String AUSTRALIA = "Australia/Adelaide";
    static final long AUSTRALIA_1997_BEG = 877797000000L;
    static final long AUSTRALIA_1997_END = 859653000000L;

    /**
     * Date.toString().substring() Boundary Test
     * Look for a DST changeover to occur within 6 months of the given Date.
     * The initial Date.toString() should yield a string containing the
     * startMode as a SUBSTRING.  The boundary will be tested to be
     * at the expectedBoundary value.
     */
    void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
    {
        // Given a date with a year start, find the Daylight onset
        // and end.  The given date should be 1/1/xx in some year.

        if (d.toString().indexOf(startMode) == -1)
        {
            System.out.println("Error: " + startMode + " not present in " + d);
        }

        // Use a binary search, assuming that we have a Standard
        // time at the midpoint.
        long min = d.getTime();
        long max = min + SIX_MONTHS;

        while ((max - min) >  INTERVAL)
        {
            long mid = (min + max) >> 1;
            String s = new Date(mid).toString();
            // logln(s);
            if (s.indexOf(startMode) != -1)
            {
                min = mid;
            }
            else
            {
                max = mid;
            }
        }

        System.out.println("Date Before: " + showDate(min));
        System.out.println("Date After:  " + showDate(max));
        long mindelta = expectedBoundary - min;
        long maxdelta = max - expectedBoundary;
        if (mindelta >= 0 && mindelta <= INTERVAL &&
            mindelta >= 0 && mindelta <= INTERVAL)
            System.out.println("PASS: Expected boundary at " + expectedBoundary);
        else
            fail("FAIL: Expected boundary at " + expectedBoundary);
    }

    void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
    {
        findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
                                          TimeZone.getDefault());
    }

    void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
                                           long expectedBoundary, TimeZone tz)
    {
        // Given a date with a year start, find the Daylight onset
        // and end.  The given date should be 1/1/xx in some year.

        // Use a binary search, assuming that we have a Standard
        // time at the midpoint.
        long min = d.getTime();
        long max = min + SIX_MONTHS;

        if (tz.inDaylightTime(d) != startsInDST)
        {
            fail("FAIL: " + tz.getID() + " inDaylightTime(" +
                  d + ") != " + startsInDST);
            startsInDST = !startsInDST; // Flip over; find the apparent value
        }

        if (tz.inDaylightTime(new Date(max)) == startsInDST)
        {
            fail("FAIL: " + tz.getID() + " inDaylightTime(" +
                  (new Date(max)) + ") != " + (!startsInDST));
            return;
        }

        while ((max - min) >  INTERVAL)
        {
            long mid = (min + max) >> 1;
            boolean isIn = tz.inDaylightTime(new Date(mid));
            if (isIn == startsInDST)
            {
                min = mid;
            }
            else
            {
                max = mid;
            }
        }

        System.out.println(tz.getID() + " Before: " + showDate(min, tz));
        System.out.println(tz.getID() + " After:  " + showDate(max, tz));

        long mindelta = expectedBoundary - min;
        long maxdelta = max - expectedBoundary;
        if (mindelta >= 0 && mindelta <= INTERVAL &&
            mindelta >= 0 && mindelta <= INTERVAL)
            System.out.println("PASS: Expected boundary at " + expectedBoundary);
        else
            fail("FAIL: Expected boundary at " + expectedBoundary);
    }

    private static String showDate(long l)
    {
        return showDate(new Date(l));
    }

    @SuppressWarnings("deprecation")
    private static String showDate(Date d)
    {
        return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
            " " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
            " \"" + d + "\" = " +
            d.getTime();
    }

    private static String showDate(long l, TimeZone z)
    {
        return showDate(new Date(l), z);
    }

    @SuppressWarnings("deprecation")
    private static String showDate(Date d, TimeZone zone)
    {
        DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
        fmt.setTimeZone(zone);
        return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
            " " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
            " \"" + d + "\" = " +
            fmt.format(d);
    }

    private static String showNN(int n)
    {
        return ((n < 10) ? "0" : "") + n;
    }

    /**
     * Given a date, a TimeZone, and expected values for inDaylightTime,
     * useDaylightTime, zone and DST offset, verify that this is the case.
     */
    void verifyDST(Date d, TimeZone time_zone,
                   boolean expUseDaylightTime, boolean expInDaylightTime,
                   int expZoneOffset, int expDSTOffset)
    {
        System.out.println("-- Verifying time " + d +
              " in zone " + time_zone.getID());

        if (time_zone.inDaylightTime(d) == expInDaylightTime)
            System.out.println("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
        else
            fail("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));

        if (time_zone.useDaylightTime() == expUseDaylightTime)
            System.out.println("PASS: useDaylightTime = " + time_zone.useDaylightTime());
        else
            fail("FAIL: useDaylightTime = " + time_zone.useDaylightTime());

        if (time_zone.getRawOffset() == expZoneOffset)
            System.out.println("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
        else
            fail("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
                  "; expected " + expZoneOffset/(double)ONE_HOUR);

        GregorianCalendar gc = new GregorianCalendar(time_zone);
        gc.setTime(d);
        int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
                                         gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
                                         ((gc.get(gc.HOUR_OF_DAY) * 60 +
                                           gc.get(gc.MINUTE)) * 60 +
                                          gc.get(gc.SECOND)) * 1000 +
                                         gc.get(gc.MILLISECOND));
        if (offset == expDSTOffset)
            System.out.println("PASS: getOffset() = " + offset/(double)ONE_HOUR);
        else
            fail("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
                  "; expected " + expDSTOffset/(double)ONE_HOUR);
    }

    @SuppressWarnings("deprecation")
    @Test
    public void TestBoundaries()
    {
        TimeZone pst = TimeZone.getTimeZone("America/Los_Angeles");
        TimeZone save = TimeZone.getDefault();
        try {
            TimeZone.setDefault(pst);

            // DST changeover for PST is 4/6/1997 at 2 hours past midnight
            Date d = new Date(97,Calendar.APRIL,6);

            // i is minutes past midnight standard time
            for (int i=60; i<=180; i+=15)
            {
                boolean inDST = (i >= 120);
                Date e = new Date(d.getTime() + i*60*1000);
                verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
                          inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
            }

            System.out.println("========================================");
            findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
            System.out.println("========================================");
            findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);

            // Southern hemisphere test
            System.out.println("========================================");
            TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
            findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);

            System.out.println("========================================");
            findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
            System.out.println("========================================");
            findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
        } finally {
            TimeZone.setDefault(save);
        }
    }

    void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
    {
        // Given a date with a year start, find the Daylight onset
        // and end.  The given date should be 1/1/xx in some year.

        // Use a binary search, assuming that we have a Standard
        // time at the midpoint.
        long min = d.getTime();
        long max = min + (long)(365.25 / 2 * ONE_DAY);

        // First check the boundaries
        boolean startsInDST = tz.inDaylightTime(d);

        if (tz.inDaylightTime(new Date(max)) == startsInDST)
        {
            System.out.println("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
        }

        while ((max - min) >  INTERVAL)
        {
            long mid = (min + max) >> 1;
            if (tz.inDaylightTime(new Date(mid)) == startsInDST)
            {
                min = mid;
            }
            else
            {
                max = mid;
            }
        }

        System.out.println("Binary Search Before: " + showDate(min));
        System.out.println("Binary Search After:  " + showDate(max));

        long mindelta = expectedBoundary - min;
        long maxdelta = max - expectedBoundary;
        if (mindelta >= 0 && mindelta <= INTERVAL &&
            mindelta >= 0 && mindelta <= INTERVAL)
            System.out.println("PASS: Expected boundary at " + expectedBoundary);
        else
            fail("FAIL: Expected boundary at " + expectedBoundary);
    }

    /**
     * Test new rule formats.
     */
    @SuppressWarnings("deprecation")
    @Test
    public void TestNewRules() {
        // Doesn't matter what the default TimeZone is here, since we
        // are creating our own TimeZone objects.

        SimpleTimeZone tz;

        System.out.println("-----------------------------------------------------------------");
        System.out.println("Aug 2ndTues .. Mar 15");
        tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
                                Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
                                Calendar.MARCH, 15, 0, 2*ONE_HOUR);
        System.out.println("========================================");
        testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
        System.out.println("========================================");
        testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);

        System.out.println("-----------------------------------------------------------------");
        System.out.println("Apr Wed>=14 .. Sep Sun<=20");
        tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
                                Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
                                Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
        System.out.println("========================================");
        testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
        System.out.println("========================================");
        testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
    }

    /**
     * Find boundaries by stepping.
     */
    @SuppressWarnings("deprecation")
    void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
    {
        Date d = new Date(year - 1900, Calendar.JANUARY, 1);
        long time = d.getTime(); // ms
        long limit = time + ONE_YEAR + ONE_DAY;
        boolean lastState = z.inDaylightTime(d);
        int changes = 0;
        System.out.println("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
        System.out.println("useDaylightTime = " + z.useDaylightTime());
        while (time < limit)
        {
            d.setTime(time);
            boolean state = z.inDaylightTime(d);
            if (state != lastState)
            {
                System.out.println((state ? "Entry " : "Exit ") +
                      "at " + d);
                lastState = state;
                ++changes;
            }
            time += interval;
        }
        if (changes == 0)
        {
            if (!lastState && !z.useDaylightTime()) System.out.println("No DST");
            else fail("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime");
        }
        else if (changes != 2)
        {
            fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2");
        }
        else if (!z.useDaylightTime())
        {
            fail("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen");
        }
        if (changes != expectedChanges)
        {
            fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges);
        }
    }

    @Test
    public void TestStepwise()
    {
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Australia/Darwin"), 0);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Pacific/Honolulu"), 0);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST8PDT"), 2);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST"), 0);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST8PDT"), 2);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Japan"), 0);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Europe/Paris"), 2);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("America/Los_Angeles"), 2);
        findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
    }
}
