/************************************************************************
 *
 * 22.locale.money.get.mt.cpp
 *
 * test exercising the thread safety of the money_get facet
 *
 * $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 <ios>        // for ios
#include <iterator>   // for ostreambuf_iterator
#include <locale>     // for locale, money_get

#include <cstring>    // for strlen()

#include <rw_locale.h>
#include <rw_thread.h>
#include <driver.h>
#include <valcmp.h>    // for rw_strncmp ()


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

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

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

// number of locales to use
int rw_opt_nlocales = MAX_THREADS;

// should all threads share the same set of locale objects instead
// of creating their own?
int rw_opt_shared_locale;

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

// 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;

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

//
struct MyMoneyData
{
    enum { BufferSize = 16 };

    enum GetId {
        get_ldbl,
        get_string,
        get_max
    };

    // name of the locale the data corresponds to
    const char* locale_name_;

    // optionally set to the named locale for threads to share
    std::locale locale_;

    // international or domestic format flag
    bool intl_;

    //
    long double units_;

    // narrow locale specific representations of units_
    char ncs_ [BufferSize];
    std::string ncs_digits_;

#ifndef _RWSTD_NO_WCHAR_T

    // wide locale specific representations of units_
    wchar_t wcs_ [BufferSize];
    std::wstring wcs_digits_;

#endif // _RWSTD_NO_WCHAR_T

} my_money_data [MAX_THREADS];


template <class charT, class Traits>
struct MyIos: std::basic_ios<charT, Traits>
{
    MyIos () {
        this->init (0);
    }
};


template <class charT, class Traits>
struct MyStreambuf: std::basic_streambuf<charT, Traits>
{
    typedef std::basic_streambuf<charT, Traits> Base;

    MyStreambuf ()
        : Base () {
    }

    void pubsetg (const charT *gbeg, std::streamsize n) {
        this->setg (_RWSTD_CONST_CAST (charT*, gbeg),
                    _RWSTD_CONST_CAST (charT*, gbeg),
                    _RWSTD_CONST_CAST (charT*, gbeg) + n);
    }

    void pubsetp (charT *pbeg, std::streamsize n) {
        this->setp (pbeg, pbeg + n);
    }
};


extern "C" {

bool test_char;    // exercise money_get<char>
bool test_wchar;   // exercise money_get<wchar_t>


static void*
thread_func (void*)
{
    MyIos<char, std::char_traits<char> >       nio;
    MyStreambuf<char, std::char_traits<char> > nsb;
    std::basic_string<char, std::char_traits<char>  > str;
    nio.rdbuf (&nsb);

#ifndef _RWSTD_NO_WCHAR_T
    MyIos<wchar_t, std::char_traits<wchar_t> >       wio;
    MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
    std::basic_string<wchar_t, std::char_traits<wchar_t>  > wstr;
    wio.rdbuf (&wsb);
#endif // _RWSTD_NO_WCHAR_T

    std::ios_base::iostate state = std::ios_base::goodbit;

#ifndef _RWSTD_NO_LONG_DOUBLE
    long double ldbl = 0.;
#endif  // _RWSTD_NO_LONG_DOUBLE

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

        // save the name of the locale
        const MyMoneyData& data = my_money_data [i % nlocales];

        // construct a named locale, get a reference to the money_get
        // facet from it and use it to format a random money value
        const std::locale loc =
            rw_opt_shared_locale ? data.locale_
                                 : std::locale (data.locale_name_);

        if (test_char) {
            // exercise the narrow char specialization of the facet

            const std::money_get<char> &ng =
                std::use_facet<std::money_get<char> >(loc);

            nio.imbue (loc);
            nsb.pubsetg (data.ncs_, RW_COUNT_OF (data.ncs_));

            if (i & 1) {
                ng.get (std::istreambuf_iterator<char>(&nsb),
                        std::istreambuf_iterator<char>(),
                        data.intl_, nio, state, ldbl);
                RW_ASSERT (! (state & std::ios_base::failbit));
                RW_ASSERT (! rw_ldblcmp (ldbl, data.units_));
            }
            else {
                ng.get (std::istreambuf_iterator<char>(&nsb),
                        std::istreambuf_iterator<char>(),
                        data.intl_, nio, state, str);
                RW_ASSERT (! (state & std::ios_base::failbit));
                RW_ASSERT (! rw_strncmp (str.c_str (),
                                         data.ncs_digits_.c_str ()));
            }
        }

        // both specializations may be tested at the same time

        if (test_wchar) {
            // exercise the wide char specialization of the facet

#ifndef _RWSTD_NO_WCHAR_T

            const std::money_get<wchar_t> &wg =
                std::use_facet<std::money_get<wchar_t> >(loc);

            wio.imbue (loc);
            wsb.pubsetg (data.wcs_, RW_COUNT_OF (data.wcs_));

            if (i & 1) {
                wg.get (std::istreambuf_iterator<wchar_t>(&wsb),
                        std::istreambuf_iterator<wchar_t>(),
                        data.intl_, wio, state, ldbl);
                RW_ASSERT (! (state & std::ios_base::failbit));
                RW_ASSERT (! rw_ldblcmp (ldbl, data.units_));
            }
            else {
                wg.get (std::istreambuf_iterator<wchar_t>(&wsb),
                        std::istreambuf_iterator<wchar_t>(),
                        data.intl_, wio, state, wstr);
                RW_ASSERT (! (state & std::ios_base::failbit));
                RW_ASSERT (! rw_strncmp(wstr.c_str (),
                                        data.wcs_digits_.c_str ()));
            }

#endif   // _RWSTD_NO_WCHAR_T

        }
    }

    return 0;
}

}   // extern "C"

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

static int
run_test (int, char**)
{
    MyIos<char, std::char_traits<char> >       nio;
    MyStreambuf<char, std::char_traits<char> > nsb;
    nio.rdbuf (&nsb);

#ifndef _RWSTD_NO_WCHAR_T
    MyIos<wchar_t, std::char_traits<wchar_t> >       wio;
    MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
    wio.rdbuf (&wsb);
#endif // _RWSTD_NO_WCHAR_T

    // 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 = RW_COUNT_OF (locales);

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

        const std::size_t inx = nlocales;
        locales [inx] = name;

        // fill in the money and results for this locale
        MyMoneyData& data = my_money_data [inx];
        data.locale_name_ = name;

        try {
            const std::locale loc (data.locale_name_);

            // exercise domestic formats every other iteration
            // and international formats the rest
            data.intl_ = 0 == (inx & 5);

            // initialize with random but valid values
            long double units = 1.f + inx;

            // exercise postive and negative values
            if (inx & 1)
                units += (units * 3.14159);
            else
                units -= (units * 2.71828);

            // local scope
            {
                const std::money_put<char> &np =
                    std::use_facet<std::money_put<char> >(loc);

                const std::money_get<char> &ng =
                    std::use_facet<std::money_get<char> >(loc);

                std::ios::iostate state = std::ios::goodbit;

                nio.imbue (loc);

                // write the value to buffer from long double
                nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_));
                *np.put (std::ostreambuf_iterator<char>(&nsb),
                         data.intl_, nio, ' ', units) = '\0';

                rw_fatal (!nio.fail (), __FILE__, __LINE__,
                          "money_put<char>::put(...) "
                          "failed for locale(%#s)", data.locale_name_);

                // read the value back so threads know what to expect
                nsb.pubsetg (data.ncs_, RW_COUNT_OF (data.ncs_));
                ng.get (std::istreambuf_iterator<char>(&nsb),
                        std::istreambuf_iterator<char>(),
                        data.intl_, nio, state, data.units_);

                // read back as string, again for threads
                nsb.pubsetg (data.ncs_, RW_COUNT_OF (data.ncs_));
                ng.get (std::istreambuf_iterator<char>(&nsb),
                        std::istreambuf_iterator<char>(),
                        data.intl_, nio, state, data.ncs_digits_);

                if (state & std::ios_base::failbit)
                    continue;
            }

#ifndef _RWSTD_NO_WCHAR_T

            // local scope
            {
                const std::money_put<wchar_t> &wp =
                    std::use_facet<std::money_put<wchar_t> >(loc);

                const std::money_get<wchar_t> &wg =
                    std::use_facet<std::money_get<wchar_t> >(loc);

                std::ios::iostate state = std::ios::goodbit;

                wio.imbue (loc);

                // write the value to buffer from long double
                wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_));
                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
                         data.intl_, wio, L' ', units) = L'\0';

                rw_fatal (!nio.fail (), __FILE__, __LINE__,
                           "money_put<wchar_t>::put(...) "
                           "failed for locale(%#s)", data.locale_name_);

                // read back as string, again for threads
                wsb.pubsetg (data.wcs_, RW_COUNT_OF (data.wcs_));
                wg.get (std::istreambuf_iterator<wchar_t>(&wsb),
                        std::istreambuf_iterator<wchar_t>(),
                        data.intl_, wio, state, data.wcs_digits_);

                if (state & std::ios_base::failbit)
                    continue;
            }

#endif // _RWSTD_NO_WCHAR_T

            if (rw_opt_shared_locale)
                data.locale_ = loc;

            nlocales += 1;

        }
        catch (...) {
            rw_warn (!rw_opt_locales, 0, __LINE__,
                     "failed to create locale(%#s)", name);
        }

        if (nlocales == maxinx || nlocales == std::size_t (rw_opt_nlocales))
            break;
    }

    // avoid divide by zero in thread if there are no locales to test
    rw_fatal (nlocales != 0, 0, __LINE__,
              "failed to create one or more usable locales!");

    rw_info (0, 0, 0,
             "testing std::money_get<charT> with %d thread%{?}s%{;}, "
             "%zu iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }",
             rw_opt_nthreads, 1 != rw_opt_nthreads,
             rw_opt_nloops, 1 != rw_opt_nloops,
             nlocales, int (nlocales), "%#s", locales);

    rw_info (0, 0, 0, "exercising std::money_get<char>");

    test_char  = true;
    test_wchar = false;

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

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

#ifndef _RWSTD_NO_WCHAR_T

    rw_info (0, 0, 0, "exercising std::money_get<wchar_t>");

    test_char  = false;
    test_wchar = true;

    // start a pool of threads to exercise wstring thread safety
    result =
        rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0);

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

    // exercise both the char and the wchar_t specializations
    // at the same time

    rw_info (0, 0, 0,
             "exercising both std::money_get<char> "
             "and std::money_get<wchar_t>");

    test_char  = true;
    test_wchar = true;

    // start a pool of threads to exercise wstring thread safety
    result =
        rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0);

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

#endif   // _RWSTD_NO_WCHAR_T

    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
    rw_opt_nthreads = rw_get_cpus ();
    if (rw_opt_nthreads < 2)
        rw_opt_nthreads = 2;

#endif   // _RWSTD_REENTRANT

    return rw_test (argc, argv, __FILE__,
                    "lib.locale.money.get",
                    "thread safety", run_test,
                    "|-nloops#0 "        // must be non-negative
                    "|-nthreads#0-* "    // must be in [0, MAX_THREADS]
                    "|-nlocales#0 "      // arg must be non-negative
                    "|-locales= "        // must be provided
                    "|-shared-locale# ",
                    &rw_opt_nloops,
                    int (MAX_THREADS),
                    &rw_opt_nthreads,
                    &rw_opt_nlocales,
                    &rw_opt_setlocales,
                    &rw_opt_shared_locale);
}
