/************************************************************************
 *
 * 22.locale.cons.mt.cpp
 *
 * test exercising the thread safety of locale ctors
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 **************************************************************************/

#include <locale>     // for locale

#include <cstring>    // for strlen()

#include <rw_locale.h>
#include <rw_thread.h>   // for rw_get_processors (), rw_thread_pool()
#include <rw_driver.h>


// maximum number of threads allowed by the command line interface
#define MAX_THREADS   32

// default number of threads (will be adjusted to the number
// of processors/cores later)
int opt_nthreads = 1;

// the number of times each thread should iterate (unless specified
// otherwise on the command line)
int opt_nloops = 20000;

// tristate flag set in response to the --no-combine/--enable-combine
// command line option
int opt_combine;

// default timeout used by each threaded section of this test
int opt_timeout = 60;

/**************************************************************************/

// array of locale names to use for testing
static const char*
locales [MAX_THREADS];

// number of locale names in the array
static std::size_t
nlocales;

/**************************************************************************/

extern "C" {

static void*
test_ctors (void*)
{
    static const std::locale::category cats[] = {
        std::locale::all,
        std::locale::collate,
        std::locale::ctype,
        std::locale::messages,
        std::locale::monetary,
        std::locale::numeric,
        std::locale::time,
        std::locale::none
    };

    static const std::size_t ncats = sizeof cats / sizeof *cats;

    // the next locale "advanced" in each iteration of the loop
    std::locale next (locales [0]);

    for (int i = 0; i != opt_nloops; ++i) {

        if (rw_thread_pool_timeout_expired ())
            break;

        // compute an index into the array of locales
        const std::size_t linx = i % nlocales;

        // create two locale objects from the same name and verify
        // they are equal
        const std::locale first (next.name ().c_str ());
        const std::locale second (next.name ().c_str ());

        RW_ASSERT (first == second);

        // create another locale object as a copy of one of the two
        // above and verify it's equal to the other
        const std::locale third (first);

        RW_ASSERT (second == third);

        // compute the next index into the array of locales
        const std::size_t ninx = (i + 1) % nlocales;
        const char* const next_name = locales [ninx];

        // create the next locale from a name
        next = std::locale (next_name);

        if (0 <= opt_combine) {
            // compute an index into the array of categories
            const std::size_t cinx = i % ncats;
            const std::locale::category cat = cats [cinx];

            // create a locale from another object and the name of yet
            // another locale, combining some (none, one, or all) of their
            // categories
            const std::locale combined (first, next_name, cat);

            // verify that the locales were created correctly
            if (   std::locale::none == cat
#if defined (_MSC_VER) || defined (__MINGW32__)
                || std::locale::messages == cat
#endif
                || first == next) {
                RW_ASSERT (combined == first);
            }
            else if (std::locale::all == cat)
                RW_ASSERT (combined == next);
            else
                RW_ASSERT (combined != first && combined != next);

            // repeat the step above but with a locale object
            const std::locale combined_2 (first, next, cat);

            if (   std::locale::none == cat
#if defined (_MSC_VER) || defined (__MINGW32__)
                || std::locale::messages == cat
#endif
                || first == next) {
                RW_ASSERT (combined_2 == first);
            }
            else if (std::locale::all == cat)
                RW_ASSERT (combined_2 == next);
            else
                RW_ASSERT (combined_2 != first && combined_2 != next);
        }
    }

    return 0;
}

}   // extern "C"

/**************************************************************************/

static int
run_test (int, char**)
{
    // find all installed locales for which setlocale(LC_ALL) succeeds
    const char* const locale_list =
        rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL);

    const std::size_t maxinx = sizeof locales / sizeof *locales;

    for (const char *name = locale_list; *name; name += std::strlen (name) +1) {

        locales [nlocales++] = name;

        if (nlocales == maxinx)
            break;
    }

    int result;

    rw_info (0, 0, 0,
             "testing std::locale ctors with %d thread%{?}s%{;}, "
             "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }",
             opt_nthreads, 1 != opt_nthreads,
             opt_nloops, 1 != opt_nloops,
             nlocales, int (nlocales), "%#s", locales);

    // create and start a pool of threads and wait for them to finish
    result = rw_thread_pool (0, std::size_t (opt_nthreads), 0,
                             test_ctors, 0, std::size_t (opt_timeout));

    rw_error (result == 0, 0, __LINE__,
              "rw_thread_pool(0, %d, 0, %{#f}, 0) failed",
              opt_nthreads, test_ctors);

    return result;
}

/**************************************************************************/

int main (int argc, char *argv[])
{
#ifdef _RWSTD_REENTRANT

    // set nthreads to the greater of the number of processors
    // and 2 (for uniprocessor systems) by default
    opt_nthreads = rw_get_cpus ();
    if (opt_nthreads < 2)
        opt_nthreads = 2;

#endif   // _RWSTD_REENTRANT

    return rw_test (argc, argv, __FILE__,
                    "lib.locale.cons",
                    "thread safety", run_test,
                    "|-combine~ "
                    "|-soft-timeout#0 "  // must be non-negative
                    "|-nloops#0 "        // must be non-negative
                    "|-nthreads#0-* "    // must be in [0, MAX_THREADS]
                    "|-locales=",        // must be provided
                    &opt_combine,
                    &opt_timeout,
                    &opt_nloops,
                    int (MAX_THREADS),
                    &opt_nthreads,
                    &rw_opt_setlocales);
}
