
#include <iwear/uid.h>
#include <iwear/ansicolor.h>
#include <iwear/exceptions.h>
#include <iostream>

using namespace std;
using namespace iwear;

void check_smaller( const uid& u1, const uid& u2 )
{
    if ( u1 < u2 )
    {
	cout << u1 << ANSI_GREEN << " <  " << ANSI_NORMAL << u2 << endl;
    }
    else
    {
	cout << u1 << ANSI_RED << " >= " << ANSI_NORMAL << u2 << endl;
    }
}

void check_equal( const uid& u1, const uid& u2 )
{
    if ( u1 == u2 )
    {
	cout << u1 << ANSI_GREEN << " == " << ANSI_NORMAL << u2 << endl;
    }
    else
    {
	cout << u1 << ANSI_RED << " != " << ANSI_NORMAL << u2 << endl;
    }
}


void do_test( )
{

    srand(4242);
    cout << ANSI_BLUE << "Testing the uid" << ANSI_NORMAL << endl;
    cout << ANSI_BROWN << "sizeof" << ANSI_NORMAL << "(" << ANSI_GREEN << "uid" << ANSI_NORMAL << ") = " << ANSI_BLUE << sizeof(uid) << ANSI_NORMAL << endl;

    cout << ANSI_YELLOW << "Testing uid()" << ANSI_NORMAL << endl;
    uid u1("StringTest1FARTS");
    uid u2("StringTest2FARTS");
    uid u3("StringTest3FARTS");
    uid u4("StringTest4FARTS");

    cout << ANSI_YELLOW << "Testing uid( const string& )" << ANSI_NORMAL << endl;
    uid s1("TestString1SCHNACK");
    uid s2("TestString2SCHNACK");
    uid s3("TestString3SCHNACK");
    uid s4("TestString4SCHNACK");
    try
    {
	uid s5("TestString4SCHNACK");
	cout << "Did not throw when creating duplicated uid" << endl;
    }
    catch(const exception& e)
    {
	cout << e << endl;
    }

    map<uid,uint32_t> MAP;

    MAP[u1] = 1;
    MAP[u2] = 2;
    MAP[u3] = 3;
    MAP[u4] = 4;
    
    cout << ANSI_YELLOW << "Testing operator<<" << ANSI_NORMAL << endl;

    cout << u1 << endl;
    cout << u2 << endl;
    cout << u3 << endl;
    cout << u4 << endl;
    cout << s1 << endl;
    cout << s2 << endl;
    cout << s3 << endl;
    cout << s4 << endl;

    cout << ANSI_YELLOW << "Testing operator<" << ANSI_NORMAL << endl;

    check_smaller(u1,u1);
    check_smaller(u1,u2);
    check_smaller(u1,u3);
    check_smaller(u1,u4);
    check_smaller(u2,u2);
    check_smaller(u2,u3);
    check_smaller(u2,u4);
    check_smaller(u3,u3);
    check_smaller(u3,u4);


    cout << ANSI_YELLOW << "Testing operator==" << ANSI_NORMAL << endl;

    check_equal(u1,u1);
    check_equal(u1,u2);
    check_equal(u1,u3);
    check_equal(u1,u4);
    check_equal(u2,u2);
    check_equal(u2,u3);
    check_equal(u2,u4);
    check_equal(u3,u3);
    check_equal(u3,u4);
}

int main ( void )
{
    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
    enable_verbose_crash();
    do_test();

    return 0;
}
