//
// test algorithm for our boyer-moore implementation
//
#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include "..\..\common\bmbinbin.h"

#define BUFFER_SIZE (1024*1024)*10
#define SEARCHES_PER_ITERATION 50
#define MAX_PHRASE_LEN 391
#define MAX_RUN_SIZE 21

//
// search for match by finding all/any previous too
//
bool IsMatchAtPosition(unsigned char *pBuffer,
                       int nBufferLength,
                       unsigned char *pPhrase,
                       int nPhraseLength,
                       int nIsAt)
{
    CBoyerMooreHandle *phSoughtPhrase=BoyerMooreBinBin_Init(pPhrase, nPhraseLength);
    for(int nI=0;nI<nBufferLength && nI>=0;)
    {
        printf("\r ");
        nI=BoyerMooreBinBin(phSoughtPhrase,
                        pBuffer,
                        nBufferLength-nI,
                        nI);
        if(nI==nIsAt)
        {
            BoyerMooreBinBin_Deinit(phSoughtPhrase);
            return true;
        }
        // did we pass up?
        if(nI>nIsAt)
        {
            return false;
        }
        if(nI>0)
        {
            nI++;
        }
        printf("\r.");
    }
    BoyerMooreBinBin_Deinit(phSoughtPhrase);
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("\n BMTest - Test app for Boyer-Moore implementation\n");

    SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS);

    printf("\n Press any key to quit ...\n");

    printf("\n Doing static test ...");
    TCHAR *ptszTest=_T("Test me right now.");
    if(!IsMatchAtPosition((unsigned char *)ptszTest,_tcslen(ptszTest),(unsigned char *)"me r",4,5))
    {
        printf("\n  ! FAILED!\n");
    }

    unsigned char *pBuffer=new unsigned char[BUFFER_SIZE];
    srand(time(0));

    bool bQuit=false;
    int nTestTotal=0;
    while(!kbhit() && !bQuit)
    {
        printf("\r Generating random buffer ...                               ");
        for(int nI=0;nI<BUFFER_SIZE;nI++)
        {
            pBuffer[nI]=rand()%0xff;
            // do special case of repeated chars
            if(pBuffer[nI]==nI)
            {
                unsigned char c=pBuffer[nI];
                int nRunSize=rand()%MAX_RUN_SIZE;
                for(int nA=0;nI<BUFFER_SIZE && nA<nRunSize;nI++)
                {
                    pBuffer[nI]=c;
                }
            }
        }

        for(int nI=0;nI<SEARCHES_PER_ITERATION;nI++)
        {
            int nPos=rand()%(BUFFER_SIZE-1);
            int nMaxLen=MAX_PHRASE_LEN;
            if(nMaxLen>BUFFER_SIZE-nPos)
            {
                nMaxLen=BUFFER_SIZE-nPos;
            }
            int nLen=(rand()%(nMaxLen-1))+1;
            //nLen=1; //testing
            printf("\r Finding match of length %d at %d ... test %d                   ", nLen, nPos,nTestTotal+1);
            if(!IsMatchAtPosition(pBuffer,BUFFER_SIZE,pBuffer+nPos,nLen,nPos))
            {
                printf("\n ! TEST FAILED !\n Press any key to quit...");
                getch();
                bQuit=true;
                break;
            }
            nTestTotal++;
        }
    }
    delete pBuffer;

    return 0;
}