/*
 * Copyright (c) 2007, 2022, 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 5102289 6278334 8261179
 * @summary Test the default Control implementation. The expiration
 * functionality of newBundle, getTimeToLive, and needsReload is
 * tested by ExpirationTest.sh. The factory methods are tested
 * separately.
 * @build TestResourceRB
 * @build NonResourceBundle
 * @run main DefaultControlTest
 */

import java.util.*;
import static java.util.ResourceBundle.Control.*;

public class DefaultControlTest {
    // The ResourceBundle.Control instance
    static final ResourceBundle.Control CONTROL
        = ResourceBundle.Control.getControl(FORMAT_DEFAULT);

    static final ResourceBundle BUNDLE = new ResourceBundle() {
            public Enumeration<String> getKeys() { return null; }
            protected Object handleGetObject(String key) { return null; }
        };

    static final String CLAZZ = FORMAT_CLASS.get(0);

    static final String PROPERTIES = FORMAT_PROPERTIES.get(0);

    static final ClassLoader LOADER = DefaultControlTest.class.getClassLoader();

    // Full arguments for NPE testing
    static final Object[] FULLARGS = { "any",
                                       Locale.US,
                                       FORMAT_PROPERTIES.get(0),
                                       LOADER,
                                       BUNDLE };

    static int errors;

    public static void main(String[] args) {
        checkConstants();

        // Test getFormats(String)
        testGetFormats();

        // Test getCandidateLocales(String, Locale)
        testGetCandidateLocales();

        // Test getFallbackLocale(String, Locale)
        testGetFallbackLocale();

        // Test newBundle(String, Locale, String, ClassLoader, boolean)
        testNewBundle();

        // Test toBundleName(String, Locale)
        testToBundleName();

        // Test getTimeToLive(String, Locale)
        testGetTimeToLive();

        // Test needsReload(String, Locale, String, ClassLoader,
        //                  ResourceBundle, long)
        testNeedsReload();

        // Test toResourceName(String, String)
        testToResourceName();

        if (errors > 0) {
            throw new RuntimeException("FAILED: " + errors + " error(s)");
        }
    }

    private static void checkConstants() {
        // Check FORMAT_*
        if (!CONTROL.FORMAT_DEFAULT.equals(Arrays.asList("java.class",
                                                        "java.properties"))) {
            error("Wrong Control.FORMAT_DEFAULT");
        }
        checkImmutableList(CONTROL.FORMAT_DEFAULT);
        if (!CONTROL.FORMAT_CLASS.equals(Arrays.asList("java.class"))) {
            error("Wrong Control.FORMAT_CLASS");
        }
        checkImmutableList(CONTROL.FORMAT_CLASS);
        if (!CONTROL.FORMAT_PROPERTIES.equals(Arrays.asList("java.properties"))) {
            error("Wrong Control.FORMAT_PROPERTIES");
        }
        checkImmutableList(CONTROL.FORMAT_PROPERTIES);

        // Check TTL_*
        if (CONTROL.TTL_DONT_CACHE != -1) {
            error("Wrong Control.TTL_DONT_CACHE: %d%n", CONTROL.TTL_DONT_CACHE);
        }
        if (CONTROL.TTL_NO_EXPIRATION_CONTROL != -2) {
            error("Wrong Control.TTL_NO_EXPIRATION_CONTROL: %d%n",
                  CONTROL.TTL_NO_EXPIRATION_CONTROL);
        }
    }

    private static void checkImmutableList(List<String> list) {
        try {
            list.add("hello");
            error("%s is mutable%n", list);
        } catch (UnsupportedOperationException e) {
        }
    }

    private static void testGetFormats() {
        List<String> list = CONTROL.getFormats("foo");
        if (list != CONTROL.FORMAT_DEFAULT) {
            error("getFormats returned " + list);
        }
        try {
            list = CONTROL.getFormats(null);
            error("getFormats doesn't throw NPE.");
        } catch (NullPointerException e) {
        }
    }

    private static void testGetCandidateLocales() {
        Map<Locale, Locale[]> candidateData = new HashMap<Locale, Locale[]>();
        candidateData.put(Locale.of("ja", "JP", "YOK"), new Locale[] {
                              Locale.of("ja", "JP", "YOK"),
                              Locale.of("ja", "JP"),
                              Locale.of("ja"),
                              Locale.ROOT });
        candidateData.put(Locale.of("ja", "JP"), new Locale[] {
                              Locale.of("ja", "JP"),
                              Locale.of("ja"),
                              Locale.ROOT });
        candidateData.put(Locale.of("ja"), new Locale[] {
                              Locale.of("ja"),
                              Locale.ROOT });

        candidateData.put(Locale.of("ja", "", "YOK"), new Locale[] {
                              Locale.of("ja", "", "YOK"),
                              Locale.of("ja"),
                              Locale.ROOT });
        candidateData.put(Locale.of("", "JP", "YOK"), new Locale[] {
                              Locale.of("", "JP", "YOK"),
                              Locale.of("", "JP"),
                              Locale.ROOT });
        candidateData.put(Locale.of("", "", "YOK"), new Locale[] {
                              Locale.of("", "", "YOK"),
                              Locale.ROOT });
        candidateData.put(Locale.of("", "JP"), new Locale[] {
                              Locale.of("", "JP"),
                              Locale.ROOT });
        candidateData.put(Locale.ROOT, new Locale[] {
                              Locale.ROOT });

        // Norwegian Bokmal
        candidateData.put(Locale.forLanguageTag("nb-NO-POSIX"), new Locale[] {
                Locale.forLanguageTag("nb-NO-POSIX"),
                Locale.forLanguageTag("no-NO-POSIX"),
                Locale.forLanguageTag("nb-NO"),
                Locale.forLanguageTag("no-NO"),
                Locale.forLanguageTag("nb"),
                Locale.forLanguageTag("no"),
                Locale.ROOT});
        candidateData.put(Locale.forLanguageTag("no-NO-POSIX"), new Locale[] {
                Locale.forLanguageTag("no-NO-POSIX"),
                Locale.forLanguageTag("nb-NO-POSIX"),
                Locale.forLanguageTag("no-NO"),
                Locale.forLanguageTag("nb-NO"),
                Locale.forLanguageTag("no"),
                Locale.forLanguageTag("nb"),
                Locale.ROOT});


        for (Locale locale : candidateData.keySet()) {
            List<Locale> candidates = CONTROL.getCandidateLocales("any", locale);
            List<Locale> expected = Arrays.asList(candidateData.get(locale));
            if (!candidates.equals(expected)) {
                error("Wrong candidates for %s: got %s, expected %s%n",
                      toString(locale), candidates, expected);
            }
        }
        final int NARGS = 2;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            try {
                List<Locale> candidates = CONTROL.getCandidateLocales((String) data[0],
                                                                      (Locale) data[1]);
                error("getCandidateLocales(%s, %s) doesn't throw NPE.%n",
                      data[0], toString((Locale)data[1]));
            } catch (NullPointerException e) {
            }
        }
    }

    private static void testGetFallbackLocale() {
        Locale current = Locale.getDefault();
        Locale.setDefault(Locale.ITALY);
        try {
            Locale loc = CONTROL.getFallbackLocale("any", Locale.FRANCE);
            if (loc != Locale.ITALY) {
                error("getFallbackLocale: got %s, expected %s%n",
                      toString(loc), toString(Locale.ITALY));
            }
            loc = CONTROL.getFallbackLocale("any", Locale.ITALY);
            if (loc != null) {
                error("getFallbackLocale: got %s, expected null%n", toString(loc));
            }
        } finally {
            Locale.setDefault(current);
        }

        final int NARGS = 2;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            try {
                Locale loc = CONTROL.getFallbackLocale((String) data[0], (Locale) data[1]);
                error("getFallbackLocale(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
            } catch (NullPointerException e) {
            }
        }
    }

    private static void testNewBundle() {
        int testNo = 0;
        ResourceBundle rb = null;
        try {
            testNo = 1;
            rb = CONTROL.newBundle("StressOut", Locale.JAPANESE,
                                   PROPERTIES, LOADER, false);
            String s = rb.getString("data");
            if (!s.equals("Japan")) {
                error("newBundle: #%d got %s, expected Japan%n", testNo, s);
            }

            testNo = 2;
            rb = CONTROL.newBundle("TestResourceRB", Locale.ROOT,
                                   CLAZZ, LOADER, false);
            s = rb.getString("type");
            if (!s.equals(CLAZZ)) {
                error("newBundle: #%d got %s, expected %s%n", testNo, s, CLAZZ);
            }
        } catch (Throwable e) {
            error("newBundle: #%d threw %s%n", testNo, e);
            e.printStackTrace();
        }

        // Test exceptions

        try {
            // MalformedDataRB contains an invalid Unicode notation which
            // causes to throw an IllegalArgumentException.
            rb = CONTROL.newBundle("MalformedDataRB", Locale.ENGLISH,
                                   PROPERTIES, LOADER, false);
            error("newBundle: doesn't throw IllegalArgumentException with malformed data.");
        } catch (IllegalArgumentException iae) {
        } catch (Exception e) {
            error("newBundle: threw %s%n", e);
        }

        try {
            rb = CONTROL.newBundle("StressOut", Locale.JAPANESE,
                                   "foo.bar", LOADER, false);
            error("newBundle: doesn't throw IllegalArgumentException with invalid format.");
        } catch (IllegalArgumentException iae) {
        } catch (Exception e) {
            error("newBundle: threw %s%n", e);
        }

        try {
            rb = CONTROL.newBundle("NonResourceBundle", Locale.ROOT,
                                   "java.class", LOADER, false);
            error("newBundle: doesn't throw ClassCastException with a non-ResourceBundle subclass.");
        } catch (ClassCastException cce) {
        } catch (Exception e) {
            error("newBundle: threw %s%n", e);
        }

        // NPE test
        final int NARGS = 4;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            Locale loc = (Locale) data[1];
            try {
                rb = CONTROL.newBundle((String) data[0], loc,
                                       (String) data[2], (ClassLoader) data[3],
                                       false);
                error("newBundle(%s, %s, %s, %s, false) doesn't throw NPE.%n",
                      data[0], toString(loc), data[2], data[3]);
            } catch (NullPointerException npe) {
            } catch (Exception e) {
                error("newBundle(%s, %s, %s, %s, false) threw %s.%n",
                      data[0], toString(loc), data[2], data[3], e);
            }
        }
    }

    private static void testGetTimeToLive() {
        long ttl = CONTROL.getTimeToLive("any", Locale.US);
        if (ttl != CONTROL.TTL_NO_EXPIRATION_CONTROL) {
            error("getTimeToLive: got %d, expected %d%n", ttl,
                  CONTROL.TTL_NO_EXPIRATION_CONTROL);
        }
        final int NARGS = 2;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            try {
                ttl = CONTROL.getTimeToLive((String) data[0], (Locale) data[1]);
                error("getTimeToLive(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
            } catch (NullPointerException e) {
            }
        }
    }

    // The functionality of needsReload is tested by
    // ExpirationTest.sh. Only parameter checking is tested here.
    private static void testNeedsReload() {
        long loadTime = System.currentTimeMillis();

        // NPE test
        final int NARGS = 5;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            Locale loc = (Locale) data[1];
            try {
                boolean b = CONTROL.needsReload((String) data[0], loc,
                                                (String) data[2], (ClassLoader) data[3],
                                                (ResourceBundle) data[4], loadTime);
                error("needsReload(%s, %s, %s, %s, %s, loadTime) doesn't throw NPE.%n",
                      data[0], toString(loc), data[2], data[3], data[4]);
            } catch (NullPointerException e) {
            }
        }
    }

    private static void testToBundleName() {
        final String name = "J2SE";
        Map<Locale, String> bundleNames = new HashMap<Locale, String>();
        bundleNames.put(Locale.of("ja", "JP", "YOK"),
                        name + "_" + "ja" + "_" + "JP" + "_" + "YOK");
        bundleNames.put(Locale.of("ja", "JP"),
                        name + "_" + "ja" + "_" + "JP");
        bundleNames.put(Locale.of("ja"),
                        name + "_" + "ja");
        bundleNames.put(Locale.of("ja", "", "YOK"),
                        name + "_" + "ja" + "_" + "" + "_" + "YOK");
        bundleNames.put(Locale.of("", "JP", "YOK"),
                        name + "_" + "" + "_" + "JP" + "_" + "YOK");
        bundleNames.put(Locale.of("", "", "YOK"),
                        name + "_" + "" + "_" + "" + "_" + "YOK");
        bundleNames.put(Locale.of("", "JP"),
                        name + "_" + "" + "_" + "JP");
        bundleNames.put(Locale.ROOT,
                        name);

        for (Locale locale : bundleNames.keySet()) {
            String bn = CONTROL.toBundleName(name, locale);
            String expected = bundleNames.get(locale);
            if (!bn.equals(expected)) {
                error("toBundleName: got %s, expected %s%n", bn, expected);
            }
        }

        final int NARGS = 2;
        for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
            Object[] data = getNpeArgs(NARGS, mask);
            try {
                String s = CONTROL.toBundleName((String) data[0], (Locale) data[1]);
                error("toBundleName(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
            } catch (NullPointerException e) {
            }
        }
    }

    private static void testToResourceName() {
        String[][] names = {
            // bundleName,   suffix, expected result
            { "com.sun.J2SE", "xml", "com/sun/J2SE.xml" },
            { ".J2SE", "xml", "/J2SE.xml" },
            { "J2SE", "xml", "J2SE.xml" },
            { "com/sun/J2SE", "xml", "com/sun/J2SE.xml" },
            { "com.sun.J2SE", "", "com/sun/J2SE." },
            { ".", "", "/." },
            { "", "", "." },

            // data for NPE tests
            { null, "any", null },
            { "any", null, null },
            { null, null, null },
            };

        for (String[] data : names) {
            String result = null;
            boolean npeThrown = false;
            try {
                result = CONTROL.toResourceName(data[0], data[1]);
            } catch (NullPointerException npe) {
                npeThrown = true;
            }
            String expected = data[2];
            if (expected != null) {
                if (!result.equals(expected)) {
                    error("toResourceName: got %s, expected %s%n", result, data[2]);
                }
            } else {
                if (!npeThrown) {
                    error("toResourceName(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
                }
            }
        }
    }

    /**
     * Produces permutations argument data that contains at least one
     * null.
     */
    private static Object[] getNpeArgs(int length, int mask) {
        Object[] data = new Object[length];
        for (int i = 0; i < length; i++) {
            if ((mask & (1 << i)) == 0) {
                data[i] = null;
            } else {
                data[i] = FULLARGS[i];
            }
        }
        return data;
    }

    private static String toString(Locale loc) {
        if (loc == null)
            return "null";
        return "\"" + loc.getLanguage() + "_" + loc.getCountry() + "_" + loc.getVariant() + "\"";
    }

    private static void error(String msg) {
        System.out.println(msg);
        errors++;
    }

    private static void error(String fmt, Object... args) {
        System.out.printf(fmt, args);
        errors++;
    }
}
