#include <fcntl.h>
#include <unistd.h>
#include "unity/unity.h"
#include "stuffy.h"

ModuleStruct moduleTest;
int argc = 0;
char* argv[6];

void setUp(void)
{
    argv[0] = "bin/stuffy.out";
    argv[1] = "-a";
    argv[2] = "test/files/mystuffyarchive.test";
    argv[3] = "test/files/temp.test";
    argv[4] = ">";
    argv[5] = "test/files/output.test";
}

void tearDown(void)
{
    ;
}

void Test_StuffyArgument_Should_ReturnCorrectly(void)
{
    TEST_ASSERT_EQUAL(0, StuffyArgument(4, argv));
    argv[1] = "-r";
    TEST_ASSERT_EQUAL(1, StuffyArgument(4, argv));
    argv[1] = "-l";
    TEST_ASSERT_EQUAL(2, StuffyArgument(3, argv));
    argv[1] = "-e";
    TEST_ASSERT_EQUAL(3, StuffyArgument(6, argv));
    argv[1] = "-t";
    TEST_ASSERT_EQUAL(-1, StuffyArgument(4, argv));
}

void Test_IsFileArchived_Should_ReturnCorrectly(void)
{
    TEST_ASSERT_EQUAL(1, IsFileArchived(argv[2], "test/files/temp.test"));
    TEST_ASSERT_EQUAL(1, IsFileArchived(argv[2], "test/files/temp2.test"));
    TEST_ASSERT_EQUAL(1, IsFileArchived(argv[2], "test/files/temp3.test"));
    TEST_ASSERT_EQUAL(1, IsFileArchived(argv[2], "test/files/temp4.test"));
    TEST_ASSERT_EQUAL(0, IsFileArchived(argv[2], "test/files/rewio.test"));
    TEST_ASSERT_EQUAL(0, IsFileArchived(argv[2], "test/files/fake.test"));
}

void Test_StripFilename_Should_ChangeName(void)
{
    TEST_ASSERT_EQUAL_STRING("mystuffyarchive.test", StripFilename("test/files/mystuffyarchive.test"));
    TEST_ASSERT_EQUAL_STRING("temp1.test", StripFilename("test/files/temp1.test"));
    TEST_ASSERT_EQUAL_STRING("temp2.test", StripFilename("test/files/temp2.test"));
    TEST_ASSERT_EQUAL_STRING("temp3.test", StripFilename("test/files/temp3.test"));
    TEST_ASSERT_EQUAL_STRING("temp4.test", StripFilename("test/files/temp4.test"));
    TEST_ASSERT_EQUAL_STRING("temp5.test", StripFilename("test/files/temp5.test"));
}

void Test_ReadSingleModule_Should_ReadCorrectly(void)
{
    int fd = open(argv[2], O_RDONLY);
    TEST_ASSERT_EQUAL(80, ReadSingleModule(fd, &moduleTest));
    TEST_ASSERT_EQUAL(25, ReadSingleModule(fd, &moduleTest));
    TEST_ASSERT_EQUAL(27, ReadSingleModule(fd, &moduleTest));
    TEST_ASSERT_EQUAL(27, ReadSingleModule(fd, &moduleTest));
    close(fd);
}

void Test_ReadSingleModule_Should_ReadNewArchive(void)
{
    // TEST_IGNORE_MESSAGE("Implementation Required: AddToArchive");
    remove("test/files/newstuffyarchive.test");
    int fd = open("test/files/newstuffyarchive.test", O_RDONLY | O_CREAT, 0644);
    AddToArchive("test/files/newstuffyarchive.test", "test/files/temp4.test");
    TEST_ASSERT_EQUAL(27, ReadSingleModule(fd, &moduleTest));
    AddToArchive("test/files/newstuffyarchive.test", "test/files/temp3.test");
    TEST_ASSERT_EQUAL(27, ReadSingleModule(fd, &moduleTest));
    AddToArchive("test/files/newstuffyarchive.test", "test/files/temp2.test");
    TEST_ASSERT_EQUAL(25, ReadSingleModule(fd, &moduleTest));
    AddToArchive("test/files/newstuffyarchive.test", "test/files/temp.test");
    TEST_ASSERT_EQUAL(80, ReadSingleModule(fd, &moduleTest));
    AddToArchive("test/files/newstuffyarchive.test", "test/files/fake.test");
    TEST_ASSERT_EQUAL(0, ReadSingleModule(fd, &moduleTest));
    close(fd);
}

void Test_RemoveFromArchive_Should_RemoveCorrectly(void)
{
    TEST_IGNORE_MESSAGE("Implementation Required: RemoveFromArchive");
}

void Test_ListArchive_Should_ListCorrectly(void)
{
    // TEST_IGNORE_MESSAGE("Implementation Required: ListArchive");
    TEST_ASSERT_TRUE(Test_ListArchive("test/files/newstuffyarchive.test"));
    TEST_ASSERT_FALSE(Test_ListArchive("test/files/fakeArchive.test"));
}

void Test_ExtractArchive_Should_ExtractCorrectly(void)
{
    TEST_IGNORE_MESSAGE("Implementation Required: ExtractArchive");
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(Test_StuffyArgument_Should_ReturnCorrectly);
    RUN_TEST(Test_StripFilename_Should_ChangeName);
    RUN_TEST(Test_IsFileArchived_Should_ReturnCorrectly);
    RUN_TEST(Test_ReadSingleModule_Should_ReadCorrectly);
    RUN_TEST(Test_ReadSingleModule_Should_ReadNewArchive);
    RUN_TEST(Test_RemoveFromArchive_Should_RemoveCorrectly);
    RUN_TEST(Test_ListArchive_Should_ListCorrectly);
    RUN_TEST(Test_ExtractArchive_Should_ExtractCorrectly);
    return UNITY_END();
}