//
//  main.c
//  tests
//
//  Created by david van brink on 3/17/13.
//
//

#include <stdio.h>

#include "List.h"
#include "Map.h"




//
//  List.cpp
//  Wbl3001
//
//  Created by david van brink on 3/17/13.
//
//

#include "List.h"


typedef const char *cc;
typedef struct G
{
    int assertions;
    int passes;
    int fails;
} G;

G g = {0};


#define ASSERT_EQUALS_INT(_message,_want,_got) assertEqualsInt(1,__LINE__,_message,#_want,#_got,(long long)(_want),(long long)(_got))
#define ASSERT_EQUALS_INT_SHUSH(_message,_want,_got) assertEqualsInt(0,__LINE__,_message,#_want,#_got,_want,_got)
#define ASSERT_EQUALS_STRING(_message,_want,_got) assertEqualsString(_message,#_want,#_got,_want,_got)

static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,long long want,long long got);
static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,long long want,long long got)
{
    g.assertions++;
    if(got == want)
    {
        g.passes++;
        if(sayIt)
            printf("%6d.  ok       %s %s(%lld) == %s(%lld)\n",g.fails,message,wantS,want,gotS,got);
    }
    else
    {
        g.fails++;
        printf("%6d. FAIL %4d %s %s(%lld) != %s(%lld)\n",g.fails,line,message,wantS,want,gotS,got);
    }
}
//
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,unsigned long long want,unsigned long long got);
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,unsigned long long want,unsigned long long got)
//{
//    g.assertions++;
//    if(got == want)
//    {
//        g.passes++;
//        if(sayIt)
//            printf("%6d.  ok       %s %s(%lld) == %s(%lld)\n",g.fails,message,wantS,want,gotS,got);
//    }
//    else
//    {
//        g.fails++;
//        printf("%6d. FAIL %4d %s %s(%lld) != %s(%lld)\n",g.fails,line,message,wantS,want,gotS,got);
//    }
//}
//
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS, long long want,unsigned long long got);
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS, long long want,unsigned long long got)
//{
//    g.assertions++;
//    if(got == want)
//    {
//        g.passes++;
//        if(sayIt)
//            printf("%6d.  ok       %s %s(%lld) == %s(%lld)\n",g.fails,message,wantS,want,gotS,got);
//    }
//    else
//    {
//        g.fails++;
//        printf("%6d. FAIL %4d %s %s(%lld) != %s(%lld)\n",g.fails,line,message,wantS,want,gotS,got);
//    }
//}
//
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,unsigned long long want, long long got);
//static void assertEqualsInt(int sayIt,int line,cc message,cc wantS,cc gotS,unsigned long long want, long long got)
//{
//    g.assertions++;
//    if(got == want)
//    {
//        g.passes++;
//        if(sayIt)
//            printf("%6d.  ok       %s %s(%lld) == %s(%lld)\n",g.fails,message,wantS,want,gotS,got);
//    }
//    else
//    {
//        g.fails++;
//        printf("%6d. FAIL %4d %s %s(%lld) != %s(%lld)\n",g.fails,line,message,wantS,want,gotS,got);
//    }
//}

static int eq(const char *s1,const char *s2)
{
    if(s1 == s2)
        return 1;
    if(!s1 || !s2)
        return 0;
    while(*s1 || *s2)
    {
        if(*s1++ != *s2++)
            return 0;
    }
    return 1;
}


static void assertEqualsString(cc message,cc wantS,cc gotS,const char *want,const char *got)
{
    g.assertions++;
    if(eq(got,want))
    {
        g.passes++;
        printf("%6d.  ok  %s %s(%s) == %s(%s)\n",g.fails,message,wantS,want,gotS,got);
    }
    else
    {
        g.fails++;
        printf("%6d. FAIL %s %s(%s) != %s(%s)\n",g.fails,message,wantS,want,gotS,got);
    }
}


void checks4();
void checks4()
{
    Map<20,char,int> map;
    map.put('a',1);
    
    ASSERT_EQUALS_INT("get", map.get('a'), 1);
    ASSERT_EQUALS_INT("get", map.get('b'), 0);

    map.put('b',2);
    map.put('a',23);

    ASSERT_EQUALS_INT("get", map.get('a'), 23);
    ASSERT_EQUALS_INT("get", map.get('b'), 2);

    
    ASSERT_EQUALS_INT("size", 2, map.getSize());
    map.clear('a');
    ASSERT_EQUALS_INT("size", 1, map.getSize());
}
    
void checks3();
void checks3()
{
    List<100,int> intList;
    
    // make sure cant add same thing twice
    intList.add(23);
    intList.add(86);
    intList.remove(23);
    intList.remove(23);
    intList.remove(23);
    intList.remove(23);
    intList.remove(23);
    ASSERT_EQUALS_INT("list size", 1, intList.getSize());    
}
void checks2();
void checks2()
{
    List<100,int> intList;
    
    // make sure cant add same thing twice
    intList.add(23);
    intList.add(86);
    ASSERT_EQUALS_INT("list size", 2, intList.getSize());
    intList.add(23);
    intList.add(86);
    ASSERT_EQUALS_INT("list size", 2, intList.getSize());
    intList.add(99);
    intList.add(99);
    ASSERT_EQUALS_INT("list size", 3, intList.getSize());
    
    intList.clear();
    ASSERT_EQUALS_INT("list size", 0, intList.getSize());
    
}

void checks1();
void checks1()
{
    List<100,int> intList;
    
    int a = 1;
    int b = 2;
    int c = 23;
    
    intList.add(a);
    ASSERT_EQUALS_INT("add a list size", 1, intList.getSize());
    intList.add(b);
    ASSERT_EQUALS_INT("add b list size", 2, intList.getSize());
    intList.add(c);
    ASSERT_EQUALS_INT("add c list size", 3, intList.getSize());


    intList.remove(b);
    ASSERT_EQUALS_INT("rmv b list size", 2, intList.getSize());
    intList.remove(b);
    ASSERT_EQUALS_INT("rmv b list size", 2, intList.getSize());

    intList.remove(5);
    ASSERT_EQUALS_INT("rmv 5 size", 2, intList.getSize());

    intList.removeAt(0);
    ASSERT_EQUALS_INT("rmv 0 size", 1, intList.getSize());

    ASSERT_EQUALS_INT("get", 0, intList.getAt(23));

    intList.remove(c);
    ASSERT_EQUALS_INT("rmv c size", 0, intList.getSize());
}


int main(int argc, const char * argv[])
{

    checks1();
    checks2();
    checks3();
    checks4();
    
    
    printf("test results: %d pass / %d assertions\n",g.passes,g.assertions);
    if(g.fails > 0)
    {
        printf("---------------------\n");
        printf(" %d FAILED ASSERTIONS\n",g.fails);
        printf("---------------------\n");
    }
    else
    {
        printf("---------------------\n");
        printf(" aok\n");
        printf("---------------------\n");
    }
    return 0;
}

