package de.retest.recheck.persistence;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import de.retest.recheck.RecheckAdapter;
import de.retest.recheck.ui.descriptors.RootElement;

class RecheckSutStateTest {

	@Test
	void loadExpected_with_existing_folder_but_missing_retest_xml_should_return_null( @TempDir final Path temp ) {
		final File existingFolder = temp.resolve( "folder" ).toFile();
		existingFolder.mkdirs();

		assertThat( RecheckSutState.loadExpected( existingFolder ) ).isNull();
	}

	@Test
	void loadExpected_with_not_existing_file_should_return_null( @TempDir final Path temp ) {
		final File notExistingFile = temp.resolve( "asdwgerafaasd" ).toFile();

		assertThat( notExistingFile ).doesNotExist();
		assertThat( RecheckSutState.loadExpected( notExistingFile ) ).isNull();
	}

	@Test
	void convert_should_throw_exception_if_adapter_returns_null() {
		final Object convert = mock( Object.class );
		final RecheckAdapter adapter = mock( RecheckAdapter.class );
		when( adapter.convert( any() ) ).thenReturn( null );

		assertThatThrownBy( () -> RecheckSutState.convert( convert, adapter ) )
				.isInstanceOf( IllegalStateException.class );
	}

	@Test
	void convert_should_throw_exception_if_adapter_returns_empty_set() {
		final Object convert = mock( Object.class );
		final RecheckAdapter adapter = mock( RecheckAdapter.class );
		when( adapter.convert( any() ) ).thenReturn( Collections.emptySet() );

		assertThatThrownBy( () -> RecheckSutState.convert( convert, adapter ) )
				.isInstanceOf( IllegalStateException.class );
	}

	@Test
	void convert_should_create_state_if_adapter_returns_set() {
		final Object convert = mock( Object.class );
		final RecheckAdapter adapter = mock( RecheckAdapter.class );
		when( adapter.convert( any() ) ).thenReturn( Collections.singleton( mock( RootElement.class ) ) );

		assertThat( RecheckSutState.convert( convert, adapter ) ).isNotNull();
	}

	@Test
	void convert_should_respect_metadata() {
		final Object convert = mock( Object.class );
		final RecheckAdapter adapter = mock( RecheckAdapter.class );
		when( adapter.convert( any() ) ).thenReturn( Collections.singleton( mock( RootElement.class ) ) );
		final Map<String, String> metadata = new HashMap<>();
		metadata.put( "someKey", "someValue" );
		when( adapter.retrieveMetadata( any() ) ).thenReturn( metadata );

		assertThat( RecheckSutState.convert( convert, adapter ).getMetadata( "someKey" ) ).isEqualTo( "someValue" );
	}

	@Test
	void convert_should_not_check_object_is_null_and_let_adapter_handle() {
		final RecheckAdapter adapter = mock( RecheckAdapter.class );
		when( adapter.convert( any() ) ).thenReturn( Collections.singleton( mock( RootElement.class ) ) );

		assertThat( RecheckSutState.convert( null, adapter ) ).isNotNull();
		verify( adapter ).convert( null );
	}
}

@@ -625,16 +625,66 @@
 Element;
+%0Aimport de.retest.recheck.ui.descriptors.SutState;
 %0A%0Aclass 
@@ -2939,32 +2939,438 @@
 meValue%22 );%0A%09%7D%0A%0A
+%09@Test%0A%09void convert_should_add_global_metadata() throws Exception %7B%0A%09%09final Object convert = mock( Object.class );%0A%09%09final RecheckAdapter adapter = mock( RecheckAdapter.class );%0A%09%09when( adapter.convert( any() ) ).thenReturn( Collections.singleton( mock( RootElement.class ) ) );%0A%0A%09%09final SutState state = RecheckSutState.convert( convert, adapter );%0A%0A%09%09assertThat( state.getMetadata() ).isNotEmpty();%0A%09%7D%0A%0A
 %09@Test%0A%09void con

Add test for SutState to contain metadata