package de.renew.io.impl.services;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import de.renew.ioontology.ExtensionFileFilter;
import de.renew.ioontology.ExtensionFileFilterImpl;
import de.renew.ioontology.FileType;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.Mockito.mockConstruction;

class FileServiceImplTest {

    private MockedConstruction<ExtensionFileFilterImpl> _mockedConstructionExtensionFileFilterImpl;

    private Map<Object, List<Object>> _constructorArgs = new HashMap<>();

    private FileServiceImpl _service;

    @BeforeEach
    void setUp() {
        // Save arguments of constructor calls in _constructorArgs for each constructor call.
        _mockedConstructionExtensionFileFilterImpl = mockConstruction(
            ExtensionFileFilterImpl.class, (mock, context) -> _constructorArgs
                .put(mock, Arrays.asList(context.arguments().toArray())));

        _service = new FileServiceImpl();
    }

    @AfterEach
    void tearDown() {
        _mockedConstructionExtensionFileFilterImpl.close();
        _mockedConstructionExtensionFileFilterImpl = null;

        _service = null;
        _constructorArgs = null;
    }


    @Test
    void testCreateExtensionFileFilterWithStringAndString() {
        // given
        String extension = "Dummy-Extension";
        String description = "Dummy-Description";

        // when
        ExtensionFileFilter filter = _service.createExtensionFileFilter(extension, description);

        // then
        assertAll(
            () -> assertThat(_mockedConstructionExtensionFileFilterImpl)
                .returns(1, mc -> mc.constructed().size())
                .returns(filter, mc -> mc.constructed().get(0)),
            () -> assertThat(_constructorArgs.get(filter)).containsExactly(extension, description));
    }

    @Test
    void testCreateExtensionFileFilterWithFileType() {
        // given
        FileType fileType = FileType.DRAW;

        // when
        ExtensionFileFilter filter = _service.createExtensionFileFilter(fileType);

        // then
        assertAll(
            () -> assertThat(_mockedConstructionExtensionFileFilterImpl)
                .returns(1, mc -> mc.constructed().size())
                .returns(filter, mc -> mc.constructed().get(0)),
            () -> assertThat(_constructorArgs).containsOnlyKeys(filter),
            () -> assertThat(_constructorArgs.get(filter)).containsExactly(fileType));
    }
}