char __docstr__[] = "Run all autotest programs in liquid-dsp";

// default include headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <time.h>
#include <sys/resource.h>

#include "liquid.internal.h"
#include "liquid.argparse.h"
#include "liquid.autotest.h"

// list of tests
#include "autotest/liquid_autotest_registry.h"

// autotest main
int main(int argc, char* argv[])
{
    // set default logging level
    liquid_logger_set_level(NULL, LIQUID_INFO);
    //liquid_logger_set_config(NULL, LIQUID_LOG_FULL | LIQUID_LOG_COLOR);

    // define variables and parse command-line options
    liquid_argparse_init(__docstr__);
    liquid_argparse_add(char*,logfile,    "", 'g', "output logfile", NULL);
    liquid_argparse_add(char*,json,       "", 'o', "output JSON file", NULL);
    liquid_argparse_add(bool, list,    false, 'l', "list tests and exit", NULL);
    liquid_argparse_add(bool, status,  false, 'P', "print full status of all at the end", NULL);
    liquid_argparse_add(int,  test_id,    -1, 't', "run a specific test", NULL);
    liquid_argparse_add(char*,search,     "", 's', "run tests with search string in name", NULL);
    liquid_argparse_parse(argc,argv);

    if (strcmp(logfile,""))
        liquid_logger_add_filename(NULL,logfile,LIQUID_INFO);

    unsigned int i = 0;
    if (list) {
        while (liquid_autotest_registry[i] != NULL)
        {
            liquid_autotest_print_info(liquid_autotest_registry[i],i);
            i++;
        }
        return LIQUID_OK;
    }

    // mark tests to run
    i = 0;
    while (liquid_autotest_registry[i] != NULL)
    {
        struct liquid_autotest_s * test = liquid_autotest_registry[i];

        if (test_id >= 0) {
            test->status = (test_id == i) ? LIQUID_AUTOTEST_SCHED : LIQUID_AUTOTEST_SKIP;
        } else if (strlen(search) > 0) {
            test->status = (strstr(test->name,search)) != NULL ? LIQUID_AUTOTEST_SCHED : LIQUID_AUTOTEST_SKIP;
        } else {
            test->status = LIQUID_AUTOTEST_SCHED;
        }
        i++;
    }

    // run all scheduled tests
    i = 0;
    while (liquid_autotest_registry[i] != NULL)
    {
        liquid_autotest autotest = liquid_autotest_registry[i];
        if (autotest->status == LIQUID_AUTOTEST_SCHED)
        {
            liquid_autotest_execute(autotest);
        } else if (autotest->status == LIQUID_AUTOTEST_SKIP) {
            //liquid_log_trace("skipping test '%s'\n", autotest->docstr);
        }
        i++;
    }

    // print status of executed tests
    if (status)
        liquid_registry_print_status(liquid_autotest_registry);

    // print summary
    int rc = liquid_registry_print_summary(liquid_autotest_registry);

    // export output file
    if (strcmp(json,""))
        liquid_registry_json(liquid_autotest_registry, json);

    return rc;
}

