package de.renew.gui;

import java.util.Iterator;

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

import de.renew.io.api.FileApi;
import de.renew.ioontology.ExtensionFileFilter;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
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.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class CPNDrawingLoaderTest {

    private CPNDrawingLoader loader;

    @BeforeEach
    void beforeEach() {
        loader = new CPNDrawingLoader();
    }

    @Test
    void configureNetPath() {
        // TODO: write tests or remove this
    }

    @Test
    void setNetPath() {
        // TODO: write tests or remove this
    }

    @Test
    void testSetNetPath() {
        // TODO: write tests or remove this
    }

    @Test
    void addDrawing() {
        // TODO: write tests or remove this
    }

    @Test
    void releaseDrawing() {
        // TODO: write tests or remove this
    }

    /**
     * Test {@link CPNDrawingLoader#loadedDrawings()}
     * <p>
     * Test that the iterator is not null.
     * Test that the iterator is empty for an empty loader.
     * Test that the iterator returns the added drawing.
     * Test that the iterator has exactly one entry after adding a drawing to the loader.
     * </p>
     */
    @Test
    void loadedDrawings() {
        assertNotNull(loader.loadedDrawings());
        assertFalse(loader.loadedDrawings().hasNext());

        CPNDrawing drawing = new CPNDrawing();
        loader.addDrawing(drawing);

        Iterator<CPNDrawing> iterator = loader.loadedDrawings();
        assertTrue(iterator.hasNext());
        assertEquals(drawing, iterator.next());
        assertFalse(iterator.hasNext());
    }

    /**
     * Test {@link CPNDrawingLoader#getDrawing(String, boolean)}.
     * Testing {@link CPNDrawingLoader#getDrawing(String)} is unnecessary,
     * as it delegates to the other method.
     * <p>
     * Test that it does not return a Drawing when asking on a empty Loader.
     * Test that it can find a Drawing by it`s name, without using the loader.
     * </p>
     */
    @Test
    void getDrawing() {
        String randomDrawingName = "asdjioas324ß9asd";

        assertNull(loader.getDrawing(randomDrawingName));

        loader.addDrawing(new CPNDrawing());
        assertNull(loader.getDrawing(randomDrawingName));

        CPNDrawing drawing = new CPNDrawing();
        drawing.setName(randomDrawingName);
        loader.addDrawing(drawing);

        assertEquals(drawing, loader.getDrawing(randomDrawingName));
    }

    /**
     * Find a {@link CPNDrawing} via it's name.
     */
    @Test
    void findDrawing() {
        String randomDrawingName = "asdjioas324ß912";
        CPNDrawing drawing = new CPNDrawing();
        ExtensionFileFilter filter = FileApi.createExtensionFileFilter("", "empty");

        drawing.setName(randomDrawingName);
        loader.addDrawing(drawing);

        // FIXME: currently does not inspect previously loaded drawing, so will return null
        assertDoesNotThrow(() -> loader.findDrawing(randomDrawingName, filter));
    }

    /**
     * Test that {@link CPNDrawingLoader#findDrawing(String, ExtensionFileFilter)} returns {@code null}
     * and does not throw any exception, if no drawing with a given name exists.
     */
    @Test
    void doNotFindDrawing() {
        String randomDrawingName = "asdjioas324ß909";
        ExtensionFileFilter filter = FileApi.createExtensionFileFilter("", "empty");

        loader.addDrawing(new CPNDrawing());

        CPNDrawing drawingFile =
            assertDoesNotThrow(() -> loader.findDrawing(randomDrawingName, filter));
        assertNull(drawingFile);
    }

    /**
     * Test that {@link CPNDrawingLoader#findDrawingFile(String)} tries
     * to find a {@link CPNDrawing} without throwing, instead returning null.
     */
    @Test
    void doNotFindDrawingFile() {
        String randomDrawingName = "asdjioas324ß9acfg";
        CPNDrawing drawingFile =
            assertDoesNotThrow(() -> loader.findDrawingFile(randomDrawingName));
        assertNull(drawingFile);
    }
}