package de.renew.ioontology;

import java.io.File;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

/** A test class for {@link ExtensionFileFilterImpl}. */
public class ExtensionFileFilterImplTest {
    private ExtensionFileFilterImpl _fileFilter;
    private static final String FILE_TYPE_ENDING = "txt";

    @BeforeEach
    void setUp() {
        _fileFilter = new ExtensionFileFilterImpl(FILE_TYPE_ENDING, "dummyDescription");
    }

    @AfterEach
    void tearDown() {
        _fileFilter = null;
    }

    /** Tests whether a file with the same extension as the one saved in the filter is accepted. */
    @Test
    void testAcceptValidFile() {
        //when/then
        assertThat(_fileFilter.accept(new File("path/to/file." + FILE_TYPE_ENDING))).isTrue();
    }



    /** Tests whether {@code null} is not accepted. */
    @Test
    void testAcceptNull() {
        //when/then
        assertThat(_fileFilter.accept(null)).isFalse();
    }

    /** Tests whether a hidden file is not accepted. */
    @Test
    void testAcceptHiddenFile() {
        //given
        File mockedFile = Mockito.mock(File.class);
        when(mockedFile.isHidden()).thenReturn(true);
        when(mockedFile.getName()).thenReturn(".file." + FILE_TYPE_ENDING);

        //when/then
        assertThat(_fileFilter.accept(mockedFile)).isFalse();
    }

    /** Tests whether a not hidden file starting with a dot is rejected. */
    @Test
    void testAcceptFileNotHiddenButStartsWithDot() {
        //given
        File mockedFile = Mockito.mock(File.class);
        when(mockedFile.isHidden()).thenReturn(false);
        when(mockedFile.getName()).thenReturn(".file." + FILE_TYPE_ENDING);

        //when/then
        assertThat(_fileFilter.accept(mockedFile)).isFalse();
    }

    /** Tests whether {@link ExtensionFileFilterImpl#equals(Object)} is correctly overwritten. */
    @Test
    void testEqualsIsEqual() {
        //given
        ExtensionFileFilterImpl fileFilterCopy =
            new ExtensionFileFilterImpl(FILE_TYPE_ENDING, "dummyDescription");

        //when/then
        assertThat(_fileFilter.equals(fileFilterCopy)).isTrue();
    }

    /**
     * Tests whether two SimpleFileFilters are not considered
     * equal if their extensions are different.
     */
    @Test
    void testEqualsOtherExtension() {
        //given
        ExtensionFileFilterImpl fileFilterCopy =
            new ExtensionFileFilterImpl("differentExtension", "dummyDescription");

        //then
        assertThat(_fileFilter.equals(fileFilterCopy)).isFalse();
    }

    /** Tests whether objects of two different classes are correctly identified as not equal. */
    @Test
    void testEqualsOtherType() {
        //when/then
        assertThat(_fileFilter.equals(new Object())).isFalse();
    }

    /** Tests whether {@link ExtensionFileFilterImpl#hashCode()} returns a not {@code null} value. */
    @Test
    void testHashCode() {
        //when/then
        assertThat(_fileFilter.hashCode()).isNotNull();
    }
}
