/*
 * Copyright (c) 2012, 2016, 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.
 */

package test.java.time.format;

import static org.testng.Assert.assertEquals;

import java.text.DateFormatSymbols;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DecimalStyle;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalQueries;
import java.time.zone.ZoneRulesProvider;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import jdk.testlibrary.RandomFactory;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/*
 * @test
 * @bug 8081022 8151876
 * @key randomness
 */

/**
 * Test ZoneTextPrinterParser
 */
@Test
public class TestZoneTextPrinterParser extends AbstractTestPrinterParser {

    protected static DateTimeFormatter getFormatter(Locale locale, TextStyle style) {
        return new DateTimeFormatterBuilder().appendZoneText(style)
                                             .toFormatter(locale)
                                             .withDecimalStyle(DecimalStyle.of(locale));
    }

    public void test_printText() {
        Random r = RandomFactory.getRandom();
        int N = 8;
        Locale[] locales = Locale.getAvailableLocales();
        Set<String> zids = ZoneRulesProvider.getAvailableZoneIds();
        ZonedDateTime zdt = ZonedDateTime.now();

        //System.out.printf("locale==%d, timezone=%d%n", locales.length, zids.size());
        while (N-- > 0) {
            zdt = zdt.withDayOfYear(r.nextInt(365) + 1)
                     .with(ChronoField.SECOND_OF_DAY, r.nextInt(86400));
            for (String zid : zids) {
                if (zid.equals("ROC") || zid.startsWith("Etc/GMT")) {
                    continue;      // TBD: match jdk behavior?
                }
                zdt = zdt.withZoneSameLocal(ZoneId.of(zid));
                TimeZone tz = TimeZone.getTimeZone(zid);
                boolean isDST = tz.inDaylightTime(new Date(zdt.toInstant().toEpochMilli()));
                for (Locale locale : locales) {
                    String longDisplayName = tz.getDisplayName(isDST, TimeZone.LONG, locale);
                    String shortDisplayName = tz.getDisplayName(isDST, TimeZone.SHORT, locale);
                    if ((longDisplayName.startsWith("GMT+") && shortDisplayName.startsWith("GMT+"))
                            || (longDisplayName.startsWith("GMT-") && shortDisplayName.startsWith("GMT-"))) {
                        printText(locale, zdt, TextStyle.FULL, tz, tz.getID());
                        printText(locale, zdt, TextStyle.SHORT, tz, tz.getID());
                        continue;
                    }
                    printText(locale, zdt, TextStyle.FULL, tz,
                            tz.getDisplayName(isDST, TimeZone.LONG, locale));
                    printText(locale, zdt, TextStyle.SHORT, tz,
                            tz.getDisplayName(isDST, TimeZone.SHORT, locale));
                }
            }
        }
    }

    private void printText(Locale locale, ZonedDateTime zdt, TextStyle style, TimeZone zone, String expected) {
        String result = getFormatter(locale, style).format(zdt);
        if (!result.equals(expected)) {
            if (result.equals("FooLocation")) { // from rules provider test if same vm
                return;
            }
            System.out.println("----------------");
            System.out.printf("tdz[%s]%n", zdt.toString());
            System.out.printf("[%-5s, %5s] :[%s]%n", locale.toString(), style.toString(),result);
            System.out.printf(" %5s, %5s  :[%s] %s%n", "", "", expected, zone);
        }
        assertEquals(result, expected);
    }

    public void test_ParseText() {
        Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.JAPANESE, Locale.FRENCH };
        Set<String> zids = ZoneRulesProvider.getAvailableZoneIds();
        for (Locale locale : locales) {
            parseText(zids, locale, TextStyle.FULL, false);
            parseText(zids, locale, TextStyle.FULL, true);
            parseText(zids, locale, TextStyle.SHORT, false);
            parseText(zids, locale, TextStyle.SHORT, true);
        }
    }

    private static Set<ZoneId> preferred = new HashSet<>(Arrays.asList(new ZoneId[] {
        ZoneId.of("EST", ZoneId.SHORT_IDS),
        ZoneId.of("Asia/Taipei"),
        ZoneId.of("CET"),
    }));

    private static Set<ZoneId> preferred_s = new HashSet<>(Arrays.asList(new ZoneId[] {
         ZoneId.of("EST", ZoneId.SHORT_IDS),
         ZoneId.of("CET"),
         ZoneId.of("Australia/South"),
         ZoneId.of("Australia/West"),
         ZoneId.of("Asia/Shanghai"),
    }));

    private static Set<ZoneId> none = new HashSet<>();

    @DataProvider(name="preferredZones")
    Object[][] data_preferredZones() {
        return new Object[][] {
            {"America/New_York", "Eastern Standard Time", none,      Locale.ENGLISH, TextStyle.FULL},
//          {"EST",              "Eastern Standard Time", preferred, Locale.ENGLISH, TextStyle.FULL},
            {"Europe/Paris",     "Central European Time", none,      Locale.ENGLISH, TextStyle.FULL},
            {"CET",              "Central European Time", preferred, Locale.ENGLISH, TextStyle.FULL},
            {"Asia/Shanghai",    "China Standard Time",   none,      Locale.ENGLISH, TextStyle.FULL},
            {"Asia/Taipei",      "China Standard Time",   preferred, Locale.ENGLISH, TextStyle.FULL},
            {"America/Chicago",  "CST",                   none,      Locale.ENGLISH, TextStyle.SHORT},
            {"Asia/Taipei",      "CST",                   preferred, Locale.ENGLISH, TextStyle.SHORT},
            {"Australia/South",  "ACST",                  preferred_s, Locale.ENGLISH, TextStyle.SHORT},
            {"America/Chicago",  "CDT",                   none,        Locale.ENGLISH, TextStyle.SHORT},
            {"Asia/Shanghai",    "CDT",                   preferred_s, Locale.ENGLISH, TextStyle.SHORT},
       };
    }

    @Test(dataProvider="preferredZones")
    public void test_ParseText(String expected, String text, Set<ZoneId> preferred, Locale locale, TextStyle style) {
        DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneText(style, preferred)
                                                              .toFormatter(locale)
                                                              .withDecimalStyle(DecimalStyle.of(locale));

        String ret = fmt.parse(text, TemporalQueries.zone()).getId();

        System.out.printf("[%-5s %s] %24s -> %s(%s)%n",
                          locale.toString(),
                          style == TextStyle.FULL ? " full" :"short",
                          text, ret, expected);

        assertEquals(ret, expected);

    }


    private void parseText(Set<String> zids, Locale locale, TextStyle style, boolean ci) {
        System.out.println("---------------------------------------");
        DateTimeFormatter fmt = getFormatter(locale, style, ci);
        for (String[] names : new DateFormatSymbols(locale).getZoneStrings()) {
            if (!zids.contains(names[0])) {
                continue;
            }
            String zid = names[0];
            String expected = ZoneName.toZid(zid, locale);

            parse(fmt, zid, expected, zid, locale, style, ci);
            int i = style == TextStyle.FULL ? 1 : 2;
            for (; i < names.length; i += 2) {
                parse(fmt, zid, expected, names[i], locale, style, ci);
            }
        }
    }

    private void parse(DateTimeFormatter fmt,
                       String zid, String expected, String text,
                       Locale locale, TextStyle style, boolean ci) {
        if (ci) {
            text = text.toUpperCase();
        }
        String ret = fmt.parse(text, TemporalQueries.zone()).getId();
        // TBD: need an excluding list
        // assertEquals(...);
        if (ret.equals(expected) ||
            ret.equals(zid) ||
            ret.equals(ZoneName.toZid(zid)) ||
            ret.equals(expected.replace("UTC", "UCT"))) {
            return;
        }
        System.out.printf("[%-5s %s %s %16s] %24s -> %s(%s)%n",
                          locale.toString(),
                          ci ? "ci" : "  ",
                          style == TextStyle.FULL ? " full" :"short",
                          zid, text, ret, expected);
    }

    private DateTimeFormatter getFormatter(Locale locale, TextStyle style, boolean ci) {
        DateTimeFormatterBuilder db = new DateTimeFormatterBuilder();
        if (ci) {
            db = db.parseCaseInsensitive();
        }
        return db.appendZoneText(style)
                 .toFormatter(locale)
                 .withDecimalStyle(DecimalStyle.of(locale));
    }

}
