// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
 *******************************************************************************
 * Copyright (C) 2001-2013, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.ICULocaleService;
import com.ibm.icu.impl.ICUService;
import com.ibm.icu.impl.ICUService.Factory;
import com.ibm.icu.impl.ICUService.SimpleFactory;
import com.ibm.icu.util.ULocale;

@RunWith(JUnit4.class)
public class ICUServiceThreadTest extends TestFmwk
{
    private static final boolean PRINTSTATS = false;

    private static final String[] countries = {
        "ab", "bc", "cd", "de", "ef", "fg", "gh", "ji", "ij", "jk"
    };
    private static final String[] languages = {
        "", "ZY", "YX", "XW", "WV", "VU", "UT", "TS", "SR", "RQ", "QP"
    };
    private static final String[] variants = {
        "", "", "", "GOLD", "SILVER", "BRONZE"
    };

    private static class TestFactory extends SimpleFactory {
        TestFactory(String id) {
            super(new ULocale(id), id, true);
        }

        @Override
        public String getDisplayName(String idForDisplay, ULocale locale) {
            return (visible && idForDisplay.equals(this.id)) ? "(" + locale.toString() + ") " + idForDisplay : null;
        }

        @Override
        public String toString() {
            return "Factory_" + id;
        }
    }
    /**
     * Convenience override of getDisplayNames(ULocale, Comparator, String) that
     * uses the default collator for the locale as the comparator to
     * sort the display names, and null for the matchID.
     */
    public static SortedMap getDisplayNames(ICUService service, ULocale locale) {
        Collator col;
        try {
            col = Collator.getInstance(locale.toLocale());
        }
        catch (MissingResourceException e) {
            // if no collator resources, we can't collate
            col = null;
        }
        return service.getDisplayNames(locale, col, null);
    }
    private static final Random r = new Random(); // this is a multi thread test, can't 'unrandomize'

    private static String getCLV() {
        String c = countries[r.nextInt(countries.length)];
        String l = languages[r.nextInt(languages.length)];
        String v = variants[r.nextInt(variants.length)];
        return new Locale(c, l, v).toString();
    }

    private static boolean WAIT = true;
    private static boolean GO = false;
    private static long TIME = 5000;

    public static void runThreads() {
        runThreads(TIME);
    }

    public static void runThreads(long time) {
        try {
            GO = true;
            WAIT = false;

            Thread.sleep(time);

            WAIT = true;
            GO = false;

            Thread.sleep(300);
        }
        catch (InterruptedException e) {
        }
    }

    static class TestThread extends Thread {
        //private final String name;
        protected ICUService service;
        private final long delay;

        public TestThread(String name, ICUService service, long delay) {
            //this.name = name + " ";
            this.service = service;
            this.delay = delay;
            this.setDaemon(true);
        }

        @Override
        public void run() {
            while (WAIT) {
                Thread.yield();
            }

            try {
                while (GO) {
                    iterate();
                    if (delay > 0) {
                        Thread.sleep(delay);
                    }
                }
            }
            catch (InterruptedException e) {
            }
        }

        protected void iterate() {
        }

        /*
          public boolean logging() {
          return log != null;
          }

          public void log(String msg) {
          if (logging()) {
          log.log(name + msg);
          }
          }

          public void logln(String msg) {
          if (logging()) {
          log.logln(name + msg);
          }
          }

          public void err(String msg) {
          if (logging()) {
          log.err(name + msg);
          }
          }

          public void errln(String msg) {
          if (logging()) {
          log.errln(name + msg);
          }
          }

          public void warn(String msg) {
          if (logging()) {
          log.info(name + msg);
          }
          }

          public void warnln(String msg) {
          if (logging()) {
          log.infoln(name + msg);
          }
          }
        */
    }

    static class RegisterFactoryThread extends TestThread {
        RegisterFactoryThread(String name, ICUService service, long delay) {
            super("REG " + name, service, delay);
        }

        @Override
        protected void iterate() {
            Factory f = new TestFactory(getCLV());
            service.registerFactory(f);
            TestFmwk.logln(f.toString());
        }
    }

    static class UnregisterFactoryThread extends TestThread {
        private Random r;
        List factories;

        UnregisterFactoryThread(String name, ICUService service, long delay) {
            super("UNREG " + name, service, delay);

            r = new Random();
            factories = service.factories();
        }

        @Override
        public void iterate() {
            int s = factories.size();
            if (s == 0) {
                factories = service.factories();
            } else {
                int n = r.nextInt(s);
                Factory f = (Factory)factories.remove(n);
                boolean success = service.unregisterFactory(f);
                TestFmwk.logln("factory: " + f + (success ? " succeeded." : " *** failed."));
            }
        }
    }

    static class UnregisterFactoryListThread extends TestThread {
        Factory[] factories;
        int n;

        UnregisterFactoryListThread(String name, ICUService service, long delay, Factory[] factories) {
            super("UNREG " + name, service, delay);

            this.factories = factories;
        }

        @Override
        public void iterate() {
            if (n < factories.length) {
                Factory f = factories[n++];
                boolean success = service.unregisterFactory(f);
                TestFmwk.logln("factory: " + f + (success ? " succeeded." : " *** failed."));
            }
        }
    }


    static class GetVisibleThread extends TestThread {
        GetVisibleThread(String name, ICUService service, long delay) {
            super("VIS " + name, service, delay);
        }

        @Override
        protected void iterate() {
            Set ids = service.getVisibleIDs();
            Iterator iter = ids.iterator();
            int n = 10;
            while (--n >= 0 && iter.hasNext()) {
                String id = (String)iter.next();
                Object result = service.get(id);
                TestFmwk.logln("iter: " + n + " id: " + id + " result: " + result);
            }
        }
    }

    static class GetDisplayThread extends TestThread {
        ULocale locale;

        GetDisplayThread(String name, ICUService service, long delay, ULocale locale) {
            super("DIS " + name, service, delay);

            this.locale = locale;
        }

        @Override
        protected void iterate() {
            Map names = getDisplayNames(service,locale);
            Iterator iter = names.entrySet().iterator();
            int n = 10;
            while (--n >= 0 && iter.hasNext()) {
                Entry e = (Entry)iter.next();
                String dname = (String)e.getKey();
                String id = (String)e.getValue();
                Object result = service.get(id);

                // Note: IllegalMonitorStateException is thrown by the code
                // below on IBM JRE5 for AIX 64bit.  For some reason, converting
                // int to String out of this statement resolves the issue.

                String num = Integer.toString(n);
                TestFmwk.logln(" iter: " + num +
                        " dname: " + dname +
                        " id: " + id +
                        " result: " + result);
            }
        }
    }

    static class GetThread extends TestThread {
        private String[] actualID;

        GetThread(String name, ICUService service, long delay) {
            super("GET " + name, service, delay);

            actualID = new String[1];
        }

        @Override
        protected void iterate() {
            String id = getCLV();
            Object o = service.get(id, actualID);
            if (o != null) {
                TestFmwk.logln(" id: " + id + " actual: " + actualID[0] + " result: " + o);
            }
        }
    }

    static class GetListThread extends TestThread {
        private final String[] list;
        private int n;

        GetListThread(String name, ICUService service, long delay, String[] list) {
            super("GETL " + name, service, delay);

            this.list = list;
        }

        @Override
        protected void iterate() {
            if (--n < 0) {
                n = list.length - 1;
            }
            String id = list[n];
            Object o = service.get(id);
            TestFmwk.logln(" id: " + id + " result: " + o);
        }
    }

    // return a collection of unique factories, might be fewer than requested
    Collection getFactoryCollection(int requested) {
        Set locales = new HashSet();
        for (int i = 0; i < requested; ++i) {
            locales.add(getCLV());
        }
        List factories = new ArrayList(locales.size());
        Iterator iter = locales.iterator();
        while (iter.hasNext()) {
            factories.add(new TestFactory((String)iter.next()));
        }
        return factories;
    }

    void registerFactories(ICUService service, Collection c) {
        Iterator iter = c.iterator();
        while (iter.hasNext()) {
            service.registerFactory((Factory)iter.next());
        }
    }

    ICUService stableService() {
        if (stableService == null) {
            stableService = new ICULocaleService();
            registerFactories(stableService, getFactoryCollection(50));
        }
        if (PRINTSTATS) stableService.stats();  // Enable the stats collection
        return stableService;
    }
    private ICUService stableService;

    // run multiple get on a stable service
    @Test
    public void Test00_ConcurrentGet() {
        for(int i = 0; i < 10; ++i) {
            new GetThread("[" + Integer.toString(i) + "]",  stableService(), 0).start();
        }
        runThreads();
        if (PRINTSTATS) System.out.println(stableService.stats());
    }

    // run multiple getVisibleID on a stable service
    @Test
    public void Test01_ConcurrentGetVisible() {
        for(int i = 0; i < 10; ++i) {
            new GetVisibleThread("[" + Integer.toString(i) + "]",  stableService(), 0).start();
        }
        runThreads();
        if (PRINTSTATS) System.out.println(stableService.stats());
    }

    // run multiple getDisplayName on a stable service
    @Test
    public void Test02_ConcurrentGetDisplay() {
        String[] localeNames = {
            "en", "es", "de", "fr", "zh", "it", "no", "sv"
        };
        for(int i = 0; i < localeNames.length; ++i) {
            String locale = localeNames[i];
            new GetDisplayThread("[" + locale + "]",
                                 stableService(),
                                 0,
                                 new ULocale(locale)).start();
        }
        runThreads();
        if (PRINTSTATS) System.out.println(stableService.stats());
    }

    // run register/unregister on a service
    @Test
    public void Test03_ConcurrentRegUnreg() {
        ICUService service = new ICULocaleService();
        if (PRINTSTATS) service.stats();    // Enable the stats collection
        for (int i = 0; i < 5; ++i) {
            new RegisterFactoryThread("[" + i + "]", service, 0).start();
        }
        for (int i = 0; i < 5; ++i) {
            new UnregisterFactoryThread("[" + i + "]", service, 0).start();
        }
        runThreads();
        if (PRINTSTATS) System.out.println(service.stats());
    }

    @Test
    public void Test04_WitheringService() {
        ICUService service = new ICULocaleService();
        if (PRINTSTATS) service.stats();    // Enable the stats collection

        Collection fc = getFactoryCollection(50);
        registerFactories(service, fc);

        Factory[] factories = (Factory[])fc.toArray(new Factory[fc.size()]);
        Comparator comp = new Comparator() {
                @Override
                public int compare(Object lhs, Object rhs) {
                    return lhs.toString().compareTo(rhs.toString());
                }
            };
        Arrays.sort(factories, comp);

        new GetThread("", service, 0).start();
        new UnregisterFactoryListThread("", service, 3, factories).start();

        runThreads(2000);
        if (PRINTSTATS) System.out.println(service.stats());
    }

    // "all hell breaks loose"
    // one register and one unregister thread, delay 500ms
    // two display threads with different locales, delay 500ms;
    // one visible id thread, delay 50ms
    // fifteen get threads, delay 0
    // run for ten seconds
    @Test
    public void Test05_ConcurrentEverything() {
        ICUService service = new ICULocaleService();
        if (PRINTSTATS) service.stats();    // Enable the stats collection

        new RegisterFactoryThread("", service, 500).start();

        for(int i = 0; i < 15; ++i) {
            new GetThread("[" + Integer.toString(i) + "]", service, 0).start();
        }

        new GetVisibleThread("",  service, 50).start();

        String[] localeNames = {
            "en", "de"
        };
        for(int i = 0; i < localeNames.length; ++i) {
            String locale = localeNames[i];
            new GetDisplayThread("[" + locale + "]",
                                 stableService(),
                                 500,
                                 new ULocale(locale)).start();
        }

        new UnregisterFactoryThread("", service, 500).start();

        // yoweee!!!
        runThreads(9500);
        if (PRINTSTATS) System.out.println(service.stats());
    }
}
