package de.renew.formalism;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Test;

import de.renew.formalism.java.FieldSuggestion;
import de.renew.net.inscription.arc.Arc;

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

class FieldSuggestionTest {
    @Test
    public void testConstructor() throws NoSuchFieldException {
        //given
        Field testField;
        testField = Arc.Type.class.getField("OUT");
        String attemptedName = "Test String";

        //when
        FieldSuggestion testFieldSuggestion = new FieldSuggestion(testField, attemptedName);

        //then
        assertNotNull(testFieldSuggestion);
        assertEquals(testFieldSuggestion.getAttemptedName(), attemptedName);
        assertEquals(testFieldSuggestion.getField(), testField);
    }

    @Test
    public void testSuggest() {
        //given
        List<FieldSuggestion> testList = new ArrayList<FieldSuggestion>();
        String[] arcSuggestions =
            { "BOTH", "BOTH_OT", "FAST_BOTH", "FAST_TEST", "IN", "INHIBITOR", "OUT", "TEST" };

        for (Field field : Arc.Type.class.getFields()) {
            FieldSuggestion fieldSuggestion = new FieldSuggestion(field, field.getName());
            for (String arcSuggestion : arcSuggestions) {
                if (fieldSuggestion.getName().equals(arcSuggestion)) {
                    testList.add(fieldSuggestion);
                }
            }
        }
        //Sort the list by names
        Collections.sort(testList);

        //when
        List<FieldSuggestion> outputList = FieldSuggestion.suggest(Arc.Type.class, "Arc", 1);

        //then
        boolean areEqual = true;
        if (outputList.size() != testList.size()) {
            areEqual = false;
        } else {
            for (int i = 0; i < testList.size(); i++) {
                if (!outputList.get(i).toString().equals(testList.get(i).toString())) {
                    areEqual = false;
                    break;
                }
            }
        }
        assertTrue(areEqual);
    }

    @Test
    public void testToString() {
        //given
        Field testField;
        try {
            testField = Arc.Type.class.getField("OUT");
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
        String attemptedName = "Test String";
        FieldSuggestion testFieldSuggestion = new FieldSuggestion(testField, attemptedName);
        String testString = "<html>" + testField.getName() + " : "
            + testField.getType().getSimpleName() + " <font color=gray>- "
            + testField.getDeclaringClass().getSimpleName() + "</font></html>";

        //when
        String outputString = testFieldSuggestion.toString();

        //then
        assertEquals(outputString, testString);
    }
}