// Copyright (C) 2007-8 Anthony Williams
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <string>
#include <vector>

bool normal_function_called=false;

void normal_function()
{
    normal_function_called=true;
}

void test_thread_function_no_arguments()
{
    boost::thread function(normal_function);
    function.join();
    BOOST_CHECK(normal_function_called);
}

int nfoa_res=0;

void normal_function_one_arg(int i)
{
    nfoa_res=i;
}

void test_thread_function_one_argument()
{
    boost::thread function(normal_function_one_arg,42);
    function.join();
    BOOST_CHECK_EQUAL(42,nfoa_res);
}

struct callable_no_args
{
    static bool called;
    
    void operator()() const
    {
        called=true;
    }
};

bool callable_no_args::called=false;

void test_thread_callable_object_no_arguments()
{
    callable_no_args func;
    boost::thread callable(func);
    callable.join();
    BOOST_CHECK(callable_no_args::called);
}

struct callable_noncopyable_no_args:
    boost::noncopyable
{
    static bool called;
    
    void operator()() const
    {
        called=true;
    }
};

bool callable_noncopyable_no_args::called=false;

void test_thread_callable_object_ref_no_arguments()
{
    callable_noncopyable_no_args func;
    
    boost::thread callable(boost::ref(func));
    callable.join();
    BOOST_CHECK(callable_noncopyable_no_args::called);
}

struct callable_one_arg
{
    static bool called;
    static int called_arg;
    
    void operator()(int arg) const
    {
        called=true;
        called_arg=arg;
    }
};

bool callable_one_arg::called=false;
int callable_one_arg::called_arg=0;

void test_thread_callable_object_one_argument()
{
    callable_one_arg func;
    boost::thread callable(func,42);
    callable.join();
    BOOST_CHECK(callable_one_arg::called);
    BOOST_CHECK_EQUAL(callable_one_arg::called_arg,42);
}

struct callable_multiple_arg
{
    static bool called_two;
    static int called_two_arg1;
    static double called_two_arg2;
    static bool called_three;
    static std::string called_three_arg1;
    static std::vector<int> called_three_arg2;
    static int called_three_arg3;
    
    void operator()(int arg1,double arg2) const
    {
        called_two=true;
        called_two_arg1=arg1;
        called_two_arg2=arg2;
    }
    void operator()(std::string const& arg1,std::vector<int> const& arg2,int arg3) const
    {
        called_three=true;
        called_three_arg1=arg1;
        called_three_arg2=arg2;
        called_three_arg3=arg3;
    }
};

bool callable_multiple_arg::called_two=false;
bool callable_multiple_arg::called_three=false;
int callable_multiple_arg::called_two_arg1;
double callable_multiple_arg::called_two_arg2;
std::string callable_multiple_arg::called_three_arg1;
std::vector<int> callable_multiple_arg::called_three_arg2;
int callable_multiple_arg::called_three_arg3;

void test_thread_callable_object_multiple_arguments()
{
    std::vector<int> x;
    for(unsigned i=0;i<7;++i)
    {
        x.push_back(i*i);
    }

    callable_multiple_arg func;
    
    boost::thread callable3(func,"hello",x,1.2);
    callable3.join();
    BOOST_CHECK(callable_multiple_arg::called_three);
    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");
    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.size(),x.size());
    for(unsigned j=0;j<x.size();++j)
    {
        BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.at(j),x[j]);
    }
    
    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg3,1);

    double const dbl=1.234;
    
    boost::thread callable2(func,19,dbl);
    callable2.join();
    BOOST_CHECK(callable_multiple_arg::called_two);
    BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg1,19);
    BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg2,dbl);
}

struct X
{
    bool function_called;
    int arg_value;

    X():
        function_called(false),
        arg_value(0)
    {}
    

    void f0()
    {
        function_called=true;
    }

    void f1(int i)
    {
        arg_value=i;
    }

};

void test_thread_member_function_no_arguments()
{
    X x;
    
    boost::thread function(&X::f0,&x);
    function.join();
    BOOST_CHECK(x.function_called);
}


void test_thread_member_function_one_argument()
{
    X x;
    boost::thread function(&X::f1,&x,42);
    function.join();
    BOOST_CHECK_EQUAL(42,x.arg_value);
}


boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{
    boost::unit_test_framework::test_suite* test =
        BOOST_TEST_SUITE("Boost.Threads: thread launching test suite");

    test->add(BOOST_TEST_CASE(test_thread_function_no_arguments));
    test->add(BOOST_TEST_CASE(test_thread_function_one_argument));
    test->add(BOOST_TEST_CASE(test_thread_callable_object_no_arguments));
    test->add(BOOST_TEST_CASE(test_thread_callable_object_ref_no_arguments));
    test->add(BOOST_TEST_CASE(test_thread_callable_object_one_argument));
    test->add(BOOST_TEST_CASE(test_thread_callable_object_multiple_arguments));
    test->add(BOOST_TEST_CASE(test_thread_member_function_no_arguments));
    test->add(BOOST_TEST_CASE(test_thread_member_function_one_argument));
    return test;
}
