package de.renew.navigator.models;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.LinkedList;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;


/**
 * @author 1huss, 1baaske
 */
public class DirectoryTest {

    private static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(DirectoryTest.class);

    private Directory _directory1;

    @BeforeEach
    public void setup() {
        this._directory1 = new Directory();
    }

    @Test
    public void testSetChildren() {
        //given
        List<TreeElement> children = new LinkedList<>();
        Directory directory2 = new Directory();
        children.add(directory2);

        //when
        _directory1.setChildren(children);

        //then
        assertTrue(_directory1._elements.contains(directory2));
        assertEquals(children, _directory1._elements);
        assertTrue(_directory1.hasChanged());
    }

    @Test
    public void testSetOpenedTrue() {
        //given
        Directory directoryParent = new Directory();
        _directory1.setParent(directoryParent);

        //when
        _directory1.setOpened(true);

        //then
        assertTrue(_directory1.isOpened());
        assertTrue(directoryParent.isOpened());
        assertTrue(_directory1.hasChanged());
        assertTrue(directoryParent.hasChanged());
    }

    @Test
    public void testSetOpenedFalse() {
        //given
        Directory directory2 = new Directory();
        List<TreeElement> children = new LinkedList<>();
        children.add(directory2);
        _directory1.setChildren(children);

        //when
        _directory1.setOpened(false);

        //then
        assertFalse(_directory1.isOpened());
        assertFalse(directory2.isOpened());
        assertTrue(_directory1.hasChanged());
        assertTrue(directory2.hasChanged());
    }

    @Test
    public void testSetType() {
        //given
        DirectoryType directoryType = DirectoryType.TEST_SOURCE;

        //when
        _directory1.setType(directoryType);

        //then
        assertNotNull(_directory1.getType());
        assertEquals(_directory1.getType(), directoryType);
    }

    @Test
    public void testSetExcludedTrue() {
        //given
        Directory directory2 = new Directory();
        List<TreeElement> children = new LinkedList<>();
        children.add(directory2);
        _directory1.setChildren(children);

        //when
        _directory1.setExcluded(true);

        //then
        assertTrue(_directory1.isExcluded());
        assertTrue(directory2.isExcluded());
        assertTrue(_directory1.hasChanged());
        assertTrue(directory2.hasChanged());
    }

    @Test
    public void testSetExcludedFalse() {
        //given
        Directory directory2 = new Directory();
        _directory1.setParent(directory2);

        //when
        _directory1.setExcluded(false);

        //then
        assertFalse(_directory1.isExcluded());
        assertFalse(directory2.isExcluded());
        assertTrue(directory2.hasChanged());
        assertTrue(_directory1.hasChanged());
    }

    @Test
    public void testToString() {
        //given
        _directory1.setName("name");
        try {
            String temp = Files.createTempFile("hello", ".file").toString();
            File file = new File(temp);
            _directory1.setFile(file);

            Directory directory2 = new Directory();
            List<TreeElement> children = new LinkedList<>();
            children.add(directory2);
            _directory1.setChildren(children);

            String expectedResult = "TreeElement{name='name', file=" + temp + "}, elements=1";

            //when
            String result = _directory1.toString();

            //then
            assertEquals(result, expectedResult);
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }

    }

    @Test
    public void testExpandAll() {
        //given
        Directory directory2 = new Directory();
        Directory directory3 = new Directory();
        List<TreeElement> children1 = new LinkedList<>();
        List<TreeElement> children2 = new LinkedList<>();
        children1.add(directory2);
        _directory1.setChildren(children1);
        children2.add(directory3);
        directory2.setChildren(children2);

        //when
        _directory1.expandAll();

        //then
        assertTrue(_directory1.isOpened());
        assertTrue(directory2.isOpened());
        assertTrue(directory3.isOpened());
        assertTrue(_directory1.hasChanged());
        assertTrue(directory2.hasChanged());
        assertTrue(directory3.hasChanged());
    }

}