/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>

#include "test_runner.h"
#include "fileutils.h"

#include <string>
#include <iostream>
#include <cstdlib>
#include <unistd.h>

namespace dhtnet { namespace fileutils { namespace test {

class FileutilsTest : public CppUnit::TestFixture {
public:
    static std::string name() { return "fileutils"; }

    void setUp();
    void tearDown();

private:
    void testCheckDir();
    void testPath();
    void testReadDirectory();
    void testLoadFile();
    void testIsDirectoryWritable();

    CPPUNIT_TEST_SUITE(FileutilsTest);
    CPPUNIT_TEST(testCheckDir);
    CPPUNIT_TEST(testPath);
    CPPUNIT_TEST(testReadDirectory);
    CPPUNIT_TEST(testLoadFile);
    CPPUNIT_TEST(testIsDirectoryWritable);
    CPPUNIT_TEST_SUITE_END();

    static constexpr auto tmpFileName = "temp_file";

    std::string TEST_PATH;
    std::string NON_EXISTANT_PATH_BASE;
    std::string NON_EXISTANT_PATH;
    std::string EXISTANT_FILE;
};

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FileutilsTest, FileutilsTest::name());

void
FileutilsTest::setUp()
{
    char template_name[] = {"ring_unit_tests_XXXXXX"};

    // Generate a temporary directory with a file inside
    auto directory = mkdtemp(template_name);
    CPPUNIT_ASSERT(directory);

    TEST_PATH = directory;
    EXISTANT_FILE = TEST_PATH + DIR_SEPARATOR_STR + tmpFileName;
    NON_EXISTANT_PATH_BASE = TEST_PATH + DIR_SEPARATOR_STR + "not_existing_path";
    NON_EXISTANT_PATH = NON_EXISTANT_PATH_BASE + DIR_SEPARATOR_STR + "test";

    auto* fd = fopen(EXISTANT_FILE.c_str(), "w");
    fwrite("RING", 1, 4, fd);
    fclose(fd);
}

void
FileutilsTest::tearDown()
{
    unlink(EXISTANT_FILE.c_str());
    rmdir(TEST_PATH.c_str());
}

void
FileutilsTest::testCheckDir()
{
    // check existed directory
    CPPUNIT_ASSERT(check_dir(TEST_PATH.c_str()));
    CPPUNIT_ASSERT(isDirectory(TEST_PATH.c_str()));
    // check non-existent directory
    CPPUNIT_ASSERT(!isDirectory(NON_EXISTANT_PATH));
    CPPUNIT_ASSERT(check_dir(NON_EXISTANT_PATH.c_str()));
    CPPUNIT_ASSERT(isDirectory(NON_EXISTANT_PATH));
    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
    CPPUNIT_ASSERT(!isDirectory(NON_EXISTANT_PATH_BASE));
    //remove an non existent directory
    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == -1);
}

void
FileutilsTest::testPath()
{
    CPPUNIT_ASSERT(isPathRelative("relativePath"));
    CPPUNIT_ASSERT(isFile(EXISTANT_FILE));
    CPPUNIT_ASSERT(!isDirectory(EXISTANT_FILE));
    CPPUNIT_ASSERT(isDirectory(TEST_PATH));
}

void
FileutilsTest::testReadDirectory()
{
    CPPUNIT_ASSERT(recursive_mkdir(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory" + DIR_SEPARATOR_STR + "test1"));
    CPPUNIT_ASSERT(recursive_mkdir(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory" + DIR_SEPARATOR_STR + "test2"));
    auto dirs = readDirectory(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory");
    CPPUNIT_ASSERT(dirs.size() == 2);
    CPPUNIT_ASSERT(
        (dirs.at(0).compare("test1") == 0 && dirs.at(1).compare("test2") == 0)
        || (dirs.at(1).compare("test1") == 0 && dirs.at(0).compare("test2") == 0));
    CPPUNIT_ASSERT(removeAll(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory") == 0);
}

void
FileutilsTest::testLoadFile()
{
    auto file = loadFile(EXISTANT_FILE);
    CPPUNIT_ASSERT(file.size() == 4);
    CPPUNIT_ASSERT(file.at(0) == 'R');
    CPPUNIT_ASSERT(file.at(1) == 'I');
    CPPUNIT_ASSERT(file.at(2) == 'N');
    CPPUNIT_ASSERT(file.at(3) == 'G');
}

void
FileutilsTest::testIsDirectoryWritable()
{
    CPPUNIT_ASSERT(recursive_mkdir(NON_EXISTANT_PATH_BASE));
    CPPUNIT_ASSERT(isDirectoryWritable(NON_EXISTANT_PATH_BASE));
    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
    // Create directory with permission: read by owner
    CPPUNIT_ASSERT(recursive_mkdir(NON_EXISTANT_PATH_BASE, 0400));
    CPPUNIT_ASSERT(!isDirectoryWritable(NON_EXISTANT_PATH_BASE));
    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
}

}}} // namespace dhtnet::test::fileutils

JAMI_TEST_RUNNER(dhtnet::fileutils::test::FileutilsTest::name());

