/*
 * Copyright (c) 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
/*
    @test
    @summary Verify a few assertions of the new specification of ResourceBundle.getBundle
    @build Test4314141B Test4314141B_fr_CH Test4314141B_es_ES
    @run main Test4314141
    @bug 4314141
*/

import java.util.ResourceBundle;
import java.util.Locale;
import java.util.MissingResourceException;

public class Test4314141 {

    public static void main(String[] args) {
        testCandidateOmission();
        testExample();
    }

    /**
     * Tests that candidate bundle names where the final component is an empty string are omitted.
     * Previous versions of ResourceBundle might attempt to load bundles with a trailing
     * underscore (e.g., "Test4314141_") resulting from concatenation with an empty string.
     * This is no longer permitted.
     */
    static void testCandidateOmission() {
        Locale.setDefault(Locale.US);
        doTestCandidateOmission("de", "DE", "EURO", new String[] {"_de", ""});
        doTestCandidateOmission("de", "DE", "", new String[] {"_de", ""});
        doTestCandidateOmission("de", "", "EURO", new String[] {"_de", ""});
        doTestCandidateOmission("de", "", "", new String[] {"_de", ""});
        doTestCandidateOmission("", "DE", "EURO", new String[] {"__DE", ""});
        doTestCandidateOmission("", "DE", "", new String[] {"__DE", ""});
        doTestCandidateOmission("", "", "EURO", new String[] {"___EURO", ""});
        doTestCandidateOmission("", "", "", new String[] {""});
    }

    static void doTestCandidateOmission(String language, String country, String variant,
            String[] expectedSuffixes) {
        doTest("Test4314141A", language, country, variant, expectedSuffixes);
    }

    /**
     * Verifies the example from the getBundle specification.
     */
    static void testExample() {
        Locale.setDefault(new Locale("en", "UK"));
        doTestExample("fr", "CH", new String[] {"_fr_CH.class", "_fr.properties", ".class"});
        doTestExample("fr", "FR", new String[] {"_fr.properties", ".class"});
        doTestExample("de", "DE", new String[] {"_en.properties", ".class"});
        doTestExample("en", "US", new String[] {"_en.properties", ".class"});
        doTestExample("es", "ES", new String[] {"_es_ES.class", ".class"});
    }

    static void doTestExample(String language, String country, String[] expectedSuffixes) {
        doTest("Test4314141B", language, country, "", expectedSuffixes);
    }

    static void doTest(String baseName, String language, String country, String variant,
            String[] expectedSuffixes) {
        System.out.print("Looking for " + baseName + " \"" + language + "\", \"" + country + "\", \"" + variant + "\"");
        ResourceBundle bundle = ResourceBundle.getBundle(baseName, new Locale(language, country, variant));
        System.out.print(" => got ");
        String previousName = null;
        int nameCount = 0;
        for (int i = 3; i >= 0; i--) {
            String name = bundle.getString("name" + i);
            if (!name.equals(previousName)) {
                if (previousName != null) {
                    System.out.print(", ");
                }
                System.out.print(name);
                if (!name.equals(baseName + expectedSuffixes[nameCount++])) {
                    System.out.println();
                    throw new RuntimeException("Error: got unexpected resource bundle");
                }
                previousName = name;
            }
        }
        System.out.println();
        if (nameCount != expectedSuffixes.length) {
            throw new RuntimeException("Error: parent chain too short");
        }
    }
}
