/***************************************************************************
                             -------------------
    cvs         : $Id$
    begin       : Sat Aug 10 2002
    copyright   : (C) 2003 by Christian Stimming
    email       :

 ***************************************************************************
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library 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     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

#include <config.h>
#include <ktoblzcheck.h>
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <assert.h>
#include <sqlite3.h>

using namespace std;

int check_bankData_lookup(const std::string &filename, unsigned long tries = 5)
{
    unsigned long nr_found = 0,
                  nr_notfound = 0,
                  rand_blz;
    char buf[50];
    AccountNumberCheck::Record bankData;
    bool found;
    std::string bankId;

    AccountNumberCheck checker(filename);

    for (unsigned long i = 0; i < tries; i++) {
        /*
        rand_blz = (unsigned long)(double(rand())*(1e8/double(RAND_MAX)));
        sprintf(buf, "%8.8lu", rand_blz);
        buf[8]='\0';
        bankId = buf;
        */
        rand_blz = (unsigned long)(double(rand())*(1e2/double(RAND_MAX)));
        sprintf(buf, "%2.2lu", rand_blz);
        buf[2] = '\0';
        bankId = string(buf) + "000000";

        //std::cout << "testing blz " << bankId << std::endl;
        found = true;
        try {
            bankData = checker.findBank(bankId);
        } catch (int i) {
            found = false;
        }
        if (found) {
            ++nr_found;
        } else {
            ++nr_notfound;
        }
    }

    std::cout << "Tried " << tries << " banks. Found " << nr_found
              << ", not found " << nr_notfound << ", i.e. found "
              << int(100*double(nr_found)/double(tries)) << "%."
              << std::endl;
    return 0;
}

static int test_check(void *objPtr, int argc, char **argv, char **azColName)
{
    AccountNumberCheck *checker = (AccountNumberCheck *)objPtr;
    char *blz = argv[1];
    char *method = argv[3];
    char *name = argv[4];
    char *location = argv[5];
    std::string kto;

    unsigned long rand_kto = rand() % 9000000000 + 1000000000;
    kto = std::to_string(rand_kto);
    AccountNumberCheck::Result res;

    res = checker->check(blz, kto);
    std::cout << "Result of " << blz << ";" << kto << ";" << method << ";" << name
              << ": " <<checker->resultToString(res) << std::endl;
    return 0;
}

int check_testkontos(const std::string &filename)
{
    assert(filename.size() > 0);
    AccountNumberCheck checker(filename);

    sqlite3 *db;
    int retcode;
    char *zErrorMsg;
    retcode = sqlite3_open(filename.c_str(), &db);
    if (retcode) {
        std::cerr << "Cannot open database: " << sqlite3_errmsg(db)
                  << std::endl;
        exit(1);
    }

    std::string sql;
    sql = "SELECT country,bankcode,bic,method,name,location,date(valid_upto) FROM 'institutions'";
    retcode = sqlite3_exec(db, sql.c_str(), &test_check, &checker, &zErrorMsg);
    if (retcode) {
        std::cout <<zErrorMsg << std::endl;
        exit(1);
    }
    sqlite3_close(db);
    return 0;
}

void printUsage()
{
    std::cout << "Usage:\n"
              << "benchmark [<options>] tries \n"
              << "  --help, -h:             This help message\n"
              << "  --version, -v:          Print the version number and exit.\n"
              << "  --file=<bankdata-file>: Use this specified file as database\n"
    ;
}

int main(int argc, char **argv)
{
    unsigned long tries = 5;
    if (argc < 2) {
        printUsage();
        return 1;
    }
    if (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
        printUsage();
        return 1;
    } else if (argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) {
        cout << VERSION << endl;
        return 0;
    }

    const char *arg = "--file";
    std::string bankdataFile;
    if (argc > 1 && strstr(argv[1], arg)) {
        bankdataFile = argv[1]+strlen(arg)+1;
        if (argc > 2) {
            tries = atol(argv[2]);
        }
    } else if (argc == 2 && *argv[1] != '-') {
        tries = atol(argv[1]);
    } else {
        printUsage();
        return 1;
    }
    srand(time(0));

    check_bankData_lookup(bankdataFile, tries);

    check_testkontos(bankdataFile);

    return 0;
}
