/*
 *	Copyright © 2015 Matthieu DUVAL, Rudy DUCHE
 *
 *	This file is part of RizzleHash.
 *
 *	RizzleHash is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	RizzleHash is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with RizzleHash.  If not, see <http://www.gnu.org/licenses/>
 */

#include "../include/RH_ProcessBruteForce.h"

ProcessBruteForce::ProcessBruteForce()
{


}

ProcessBruteForce::ProcessBruteForce(queue<statReturn> * q,int idx,int nbInstence,string hashString,string clef,uint32_t limite,bool verbose,string hashMethode)
{
    this->init(q,idx,nbInstence,hashString,clef,limite,verbose,hashMethode);
}

void ProcessBruteForce::init(queue<statReturn> * q,int idx,int nbInstence,string hashString,string clef,uint32_t limite,bool verbose,string hashMethode)
{
    this->q = q;
    this->idx = idx;
    this->nbInstence = nbInstence;
    this->hashString = hashString;
    this->hashMethodeFunction = RH_Encryption::getFunctionHashLambda(hashMethode);
    this->clef = clef;
    this->limite = limite;
    this->verbose = verbose;
    this->nbWord = 0;


    this->indexMin = (sizeof(this->tabChar)/this->nbInstence)*this->idx;
	this->indexMax = indexMin + (sizeof(this->tabChar)/this->nbInstence);
	if(this->idx == this->nbInstence - 1 )
	{
        this->indexMax = sizeof(tabChar);
    }
}

void ProcessBruteForce::operator()()
{
    this->clock = time(NULL);// on initialise la clock locale
    this->bruteForce();
}

void ProcessBruteForce::bruteForce()
{
    this->password = new char[this->limite+1];
    this->password[0] = '\0';
    for(uint32_t i=0;i < this->limite;i++) {
        this->password[i+1] = '\0';
        this->recursiveFunction(i);
    }
}
/**
 * Here we create and test if the word is equal to our
 *
 * @param index
 */
void ProcessBruteForce::recursiveFunction(uint32_t index)
{
    if(index > 0){
        for(uint32_t i =0; i<sizeof(this->tabChar); i++){
            this->password[index] = this->tabChar[i];
            recursiveFunction(index - 1);

        }
    }
    else if(index == 0){
        for(uint32_t i = this->indexMin; i< this->indexMax; i++){
            this->password[index] = this->tabChar[i];
            string currentWord(this->password);
            string testWord =  this->hashMethodeFunction(currentWord);
            if(this->hashString == testWord){
                cout << "found :" << currentWord << endl;
                this->isFound = true;
            }
            testSpeed(currentWord);
        }
    }
}
/**
 *  Function used to get speed off the bf process
 */
void ProcessBruteForce::testSpeed(string currentWord)
{
    if(this->verbose)
    {
        time_t now = time(NULL);
        this->nbWord++;
        if(now - this->clock > 5)
        {
            statReturn stats;
            stats.isFound=this->isFound;
            stats.currentWord = currentWord;
            stats.currentProcessName = string("Process " + to_string(this->idx+1));
            stats.nbSecond = now - this->clock;
            stats.totalWords = this->nbWord;
            this->q->push(stats);
            this->clock = time(NULL);
            this->nbWord = 0;
        }
    }

}

ProcessBruteForce::~ProcessBruteForce()
{

}