/*
 * Copyright (c) 2023, 2024, 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 8304982 8174269
 * @summary Check if a warning is logged with COMPAT locale provider
 * @run main/othervm -Djava.locale.providers=COMPAT CompatWarning
 * @run main/othervm -Djava.locale.providers=SPI,COMPAT CompatWarning
 * @run main/othervm -Djava.locale.providers=COMPAT,SPI CompatWarning
 * @run main/othervm -Djava.locale.providers=JRE CompatWarning
 * @run main/othervm -Djava.locale.providers=SPI,JRE CompatWarning
 * @run main/othervm -Djava.locale.providers=JRE,SPI CompatWarning
 */

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;

public class CompatWarning {
    private static final String WARNING =
            "COMPAT locale provider has been removed";
    private static boolean logged;

    public static void main(String[] args) throws Throwable {
        File conf = new File(System.getProperty("test.src", "./src"), "compatlog.properties");
        if (!conf.canRead()) {
            throw new IOException("Can't read config file: " + conf.getAbsolutePath());
        }
        System.setProperty("java.util.logging.config.file", conf.getAbsolutePath());
        DateFormat.getInstance();
        if (!logged) {
            throw new RuntimeException("COMPAT warning message was not emitted");
        }
    }

    public static class CheckWarning extends Handler {
        @Override
        public void publish(LogRecord record) {
            var level = record.getLevel();
            var msg = record.getMessage();
            System.out.printf("""
                LogRecord emitted:
                    Level: %s
                    Message: %s
                """, level, msg);
            if (level == Level.WARNING && WARNING.equals(msg)) {
                logged = true;
            }
        }

        @Override
        public void flush() {}
        @Override
        public void close() throws SecurityException {}
    }
}
