#include <unity/unity.h>
#include <unity/unity_internals.h>
#include <vector>
#include "knapsack.hpp"
    
// Function is defined here for testing
namespace knapsack
{
    void User::_TestFileReadIn(std::vector<PossibleObject> testChoices)
    {
        TEST_ASSERT_EQUAL_INT(4, itemCount);
        TEST_ASSERT_EQUAL_INT(6, limit);
        for (int i = 0; i < itemCount; ++i)
        {
            TEST_ASSERT_EQUAL_INT(testChoices.at(i).weight, choices.at(i).weight);
            TEST_ASSERT_EQUAL_INT(testChoices.at(i).value, choices.at(i).value);
            TEST_ASSERT_EQUAL_INT(testChoices.at(i).itemNumber, choices.at(i).itemNumber);
        }
    }

    void User::_TestKnapsack(void)
    {
        RunKnapsack();
        TEST_ASSERT_NOT_EQUAL(0, solution.size());
        int resultValue = 0;
        for (auto object : solution)
            resultValue += object->value;
        TEST_ASSERT_EQUAL_INT(11, resultValue);
        TEST_ASSERT_EQUAL_INT(3, solution.size());
    }
}

void setUp(void)
{
    ;
}

void tearDown(void)
{
    ;
}

void test_User_should_ReadInDataCorrectly(void)
{
    knapsack::User testUser;
    const char* testFilename = "test/test1.txt";
    testUser.ReadNewFile(testFilename);
    std::vector<knapsack::PossibleObject> testChoices;
    testChoices.emplace_back(2, 4, 0);
    testChoices.emplace_back(1, 5, 1);
    testChoices.emplace_back(2, 1, 2);
    testChoices.emplace_back(3, 2, 3);
    testUser._TestFileReadIn(testChoices);
}

void test_KnapsackAlgorithm_should_PassTest1(void)
{
    knapsack::User testUser;
    const char* testFilename = "test/test1.txt";
    testUser.ReadNewFile(testFilename);
    testUser._TestKnapsack();
}

void test_KnapsackAlgorithm_should_PassTest2(void)
{
    knapsack::User testUser;
    const char* testFilename = "test/test2.txt";
    testUser.ReadNewFile(testFilename);
    testUser.RunKnapsack();
    TEST_ASSERT_EQUAL_INT(3, testUser.GetSolutionValue());
}

void test_KnapsackAlgorithm_should_PassTest3(void)
{
    knapsack::User testUser;
    const char* testFilename = "test/test3.txt";
    testUser.ReadNewFile(testFilename);
    testUser.RunKnapsack();
    TEST_ASSERT_EQUAL_INT(0, testUser.GetSolutionValue());
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_User_should_ReadInDataCorrectly);
    RUN_TEST(test_KnapsackAlgorithm_should_PassTest1);
    RUN_TEST(test_KnapsackAlgorithm_should_PassTest2);
    RUN_TEST(test_KnapsackAlgorithm_should_PassTest3);
    return UNITY_END();
}