/*
 * 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
 * @bug 5102289
 * @summary Stress test for ResourceBundle.getBundle with ResourceBundle.Control.
 * @run main/timeout=300/othervm -esa StressTest
 */

import java.util.*;
import java.util.concurrent.atomic.*;

public class StressTest {
    static final Locale ROOT_LOCALE = new Locale("");
    static final Random rand = new Random();
    static final Locale[] locales = {
        Locale.US,
        Locale.CHINA,
        ROOT_LOCALE,
        Locale.JAPAN,
        Locale.CANADA,
        Locale.KOREA
    };
    static final String[] expected = {
        "U.S.A.",
        "China",
        "U.S.A.",
        "Japan",
        "U.S.A.", // StressOut_en_CA.properties is empty.
        "Korea"
    };
    final static long startTime = System.currentTimeMillis();

    // increment each element when one getBundle call is done.
    static AtomicIntegerArray counters;
    static int[] prevCounters;
    static int intervalForCounterCheck;
    static AtomicInteger clearCounter = new AtomicInteger();

    static volatile boolean runrun = true;

    public static void main(String[] args) {
        int nThreads = 2;
        if (args.length > 0) {
            nThreads = Math.max(Integer.parseInt(args[0]), 2);
        }
        int nSeconds = 180;
        if (args.length > 1) {
            nSeconds = Integer.parseInt(args[1]);
        }
        Locale.setDefault(Locale.US);
        Thread[] tasks = new Thread[locales.length * nThreads];
        counters = new AtomicIntegerArray(tasks.length);

        for (int i = 0; i < tasks.length; i++) {
            tasks[i] = new Thread(new Worker(i));
        }
        for (int i = 0; i < tasks.length; i++) {
            tasks[i].start();
        }

        int nProcessors = Runtime.getRuntime().availableProcessors();
        intervalForCounterCheck = Math.max(tasks.length / nProcessors, 1);
        System.out.printf("%d processors, intervalForCounterCheck = %d [sec]%n",
                          nProcessors, intervalForCounterCheck);
        try {
            for (int i = 0; runrun && i < nSeconds; i++) {
                Thread.sleep(1000); // 1 seconds
                if ((i % intervalForCounterCheck) == 0) {
                    checkCounters();
                }
            }
            runrun = false;
            for (int i = 0; i < tasks.length; i++) {
                tasks[i].join();
            }
        } catch (InterruptedException e) {
        }

        printCounters();
    }

    static void checkCounters() {
        int length = counters.length();
        int[] snapshot = new int[length];
        for (int i = 0; i < length; i++) {
            snapshot[i] = counters.get(i);
        }

        if (prevCounters == null) {
            prevCounters = snapshot;
            return;
        }

        for (int i = 0; i < length; i++) {
            if (snapshot[i] > prevCounters[i]) {
                continue;
            }
            System.out.printf(
                "Warning: Thread #%d hasn't updated its counter for the last %d second(s).%n",
                i, intervalForCounterCheck);
        }
        prevCounters = snapshot;
    }

    static void printCounters() {
        long total = 0;
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < counters.length(); i++) {
            int counter = counters.get(i);
            total += counter;
            min = Math.min(min, counter);
            max = Math.max(max, counter);
        }
        System.out.printf("Total: %d calls, min=%d, max=%d, cache cleared %d times%n",
                          total, min, max, clearCounter.get());
    }

    static class Worker implements Runnable {
        final int id;
        final int index;
        final Locale locale;
        final String str;
        final int max;
        final boolean cleaner;
        ResourceBundle.Control control;

        Worker(int i) {
            id = i;
            index = i % locales.length;
            locale = locales[index];
            cleaner = locale.equals(ROOT_LOCALE);
            str = expected[index];
            max = rand.nextInt((index + 1) * 500) + 1000;
            control = new TestControl(max);
            System.out.println("Worker" + i + ": locale="+locale+", expected="+str+
                               ", max="+max);
        }

        public void run() {
            while (runrun) {
                ResourceBundle rb = ResourceBundle.getBundle("StressOut", locale, control);
                counters.incrementAndGet(id);
                String s = rb.getString("data");
                if (!s.equals(str)) {
                    runrun = false;
                    throw new RuntimeException(locale + ": rb.locale=" + rb.getLocale() +
                                               ", got " + s + ", expected " + str);
                }
                try {
                    Thread.sleep(rand.nextInt(max/500));
                } catch (InterruptedException e) {
                }
                if (cleaner && (rand.nextInt(10000) == 0)) {
                    //System.out.println("Clearing cache!");
                    ResourceBundle.clearCache();
                    clearCounter.incrementAndGet();
                }
            }
        }

        static class TestControl extends ResourceBundle.Control {
            int max;

            public List<Locale> getCandidateLocales(String baseName, Locale locale) {
                List<Locale> list = super.getCandidateLocales(baseName, locale);
                //System.out.println("Candidate locales=" + list);
                return list;
            }
            public TestControl(int max) {
                this.max = max;
            }
            public long getTimeToLive(String baseName, Locale locale) {
                // This will set TTL to a random value for each bundle.
                long ttl = rand.nextInt(max);
                //System.out.println("TTL: " + baseName + "_" + locale + " for " + ttl);
                return ttl;
            }
            public boolean needsReload(String baseName, Locale locale,
                                       String format, ClassLoader loader,
                                       ResourceBundle bundle, long loadTime) {
                //System.out.println("Expired: " + baseName + "_" + locale + "." + format +
                //                 " at " + (loadTime-startTime) + ", bundle=" + bundle);
                return rand.nextBoolean();
            }
        }
    }
}
