#include "TestCaseRunner.h"

#include "FileLogger.h"

#include <vector>
#include <iostream>

bool TestCaseRunner::sLastTestFailed = false;
std::string TestCaseRunner::sFailureLine = {};

TestCaseRunner::TestCaseRunner()
{

}

TestCaseRunner::~TestCaseRunner()
{

}

TestCaseRunner& TestCaseRunner::getInstance()
{
    static TestCaseRunner instance;
    return instance;
}

void TestCaseRunner::addTestCase(const std::string& label, const std::string& tag, TestCase::TestCaseFunction func)
{
    auto test_case = new TestCase(label, tag, func);
    mCases.push_back(test_case);
}

void TestCaseRunner::markTestFailure(const std::string& line)
{
    sLastTestFailed = true;
    sFailureLine = line;
}

bool TestCaseRunner::run(const std::vector<std::string>& args)
{
    std::string test_to_run;
    if (args.size() > 0 )
    {
        test_to_run = args[0];
    }
    FileLogger::GetInstance().disable();
    for (auto test_case : mCases)
    {
        if (!test_to_run.empty())
        {
            if (test_case->getName() != test_to_run)
            {
                continue;
            }
        }

        sLastTestFailed = false;
        std::cout << "TestFramework: Running Test - " << test_case->getName() << std::endl;
        test_case->run();
        if (sLastTestFailed)
        {
            std::cout << "Failed at line: " << sFailureLine << std::endl;
            mFailingTests.push_back(test_case->getName());
        }
    }

    if (mFailingTests.size() > 0)
    {
        std::cout << mFailingTests.size() << " failing tests: " << std::endl;
        for(const auto& name : mFailingTests)
        {
            std::cout << name << std::endl;
        }
    }

    return true;
}
