package completer;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import de.renew.console.completer.PropertyCompleter;
import de.renew.plugin.command.GetPropertyCommand;

import static org.assertj.core.api.Assertions.assertThat;

public class PropertyCompleterTest {


    @Test
    void testCompleteWithOneProperty() {
        //given
        List<CharSequence> candidates = new ArrayList<>();
        try (MockedStatic<GetPropertyCommand> mockedPropertyCommand =
            Mockito.mockStatic(GetPropertyCommand.class)) {
            mockedPropertyCommand.when(GetPropertyCommand::getPropertyNames)
                .thenReturn(new ArrayList<>(List.of("Property")));
            //when
            PropertyCompleter propertyCompleter = new PropertyCompleter();
            int result = propertyCompleter.complete("Pro", 3, candidates);
            //then
            assertThat(candidates).containsExactly("Property");
            assertThat(result).isZero();

        }

    }

    @Test
    void testCompleteWithMultipleProperties() {
        //given
        List<CharSequence> candidates = new ArrayList<>();
        try (MockedStatic<GetPropertyCommand> mockedPropertyCommand =
            Mockito.mockStatic(GetPropertyCommand.class)) {
            mockedPropertyCommand.when(GetPropertyCommand::getPropertyNames)
                .thenReturn(new ArrayList<>(List.of("Property", "Property2", "Property3")));
            //when
            PropertyCompleter propertyCompleter = new PropertyCompleter();
            int result = propertyCompleter.complete("Pro", 3, candidates);
            //then
            assertThat(candidates).containsExactly("Property", "Property2", "Property3");
            assertThat(result).isZero();

        }

    }

    @Test
    void testCompleteWithMultiplePropertiesDifferentNames() {
        //given
        List<CharSequence> candidates = new ArrayList<>();
        try (MockedStatic<GetPropertyCommand> mockedPropertyCommand =
            Mockito.mockStatic(GetPropertyCommand.class)) {
            mockedPropertyCommand.when(GetPropertyCommand::getPropertyNames)
                .thenReturn(new ArrayList<>(List.of("Property", "HelloWorld", "Test")));
            //when
            PropertyCompleter propertyCompleter = new PropertyCompleter();
            int result = propertyCompleter.complete("Pro", 3, candidates);
            //then
            assertThat(candidates).containsExactly("Property");
            assertThat(result).isZero();

        }

    }

    @Test
    void testCompleteNullBuffer() {
        //given
        List<CharSequence> candidates = new ArrayList<>();
        try (MockedStatic<GetPropertyCommand> mockedPropertyCommand =
            Mockito.mockStatic(GetPropertyCommand.class)) {
            mockedPropertyCommand.when(GetPropertyCommand::getPropertyNames)
                .thenReturn(new ArrayList<>(List.of("Property", "HelloWorld", "Test")));
            //when
            PropertyCompleter propertyCompleter = new PropertyCompleter();
            int result = propertyCompleter.complete(null, 3, candidates);
            //then
            assertThat(candidates).containsExactlyInAnyOrder("Property", "HelloWorld", "Test");
            assertThat(result).isZero();

        }
    }

    @Test
    void testCompleteWithNoProperty() {
        //given
        List<CharSequence> candidates = new ArrayList<>();
        try (MockedStatic<GetPropertyCommand> mockedPropertyCommand =
            Mockito.mockStatic(GetPropertyCommand.class)) {
            mockedPropertyCommand.when(GetPropertyCommand::getPropertyNames)
                .thenReturn(new ArrayList<>(List.of()));
            //when
            PropertyCompleter propertyCompleter = new PropertyCompleter();
            int result = propertyCompleter.complete("Pro", 3, candidates);
            //then
            assertThat(candidates).isEmpty();
            assertThat(result).isEqualTo(-1);

        }

    }
}
