package ch.elexis.core.services;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import ch.elexis.core.model.ICustomService;
import ch.elexis.core.model.IEncounter;
import ch.elexis.core.services.holder.ContextServiceHolder;
import ch.elexis.core.utils.OsgiServiceUtil;
import ch.rgw.tools.Money;

public class IEncounterServiceTest extends AbstractServiceTest {
	
	private IEncounter encounter;
	
	private IEncounterService encounterService =
		OsgiServiceUtil.getService(IEncounterService.class).get();
	
	private IBillingService billingService =
		OsgiServiceUtil.getService(IBillingService.class).get();
	
	@Before
	public void before(){
		createTestMandantPatientFallBehandlung();
		encounter = testEncounters.get(0);
	}
	
	@After
	public void after(){
		cleanup();
	}
	
	@Ignore("race condtion on build server")
	@Test
	public void multiThreadUpdate() throws InterruptedException{

		ExecutorService executor = Executors.newFixedThreadPool(3);
		
		for (int i = 0; i < 100; i++) {
			final int number = i;
			executor.execute(() -> {
				ContextServiceHolder.get().setActiveUser(AllServiceTests.getUser());
				ContextServiceHolder.get().setActiveMandator(testMandators.get(0));
				
				ICustomService service = coreModelService.create(ICustomService.class);
				service.setCode("code" + number);
				service.setNetPrice(new Money(number));
				service.setPrice(new Money(number));
				service.setText("test" + number);
				coreModelService.save(service);
				
				billingService.bill(service, encounter, 1.0);
			});
			executor.execute(() -> {
				encounterService.updateVersionedEntry(encounter,
					"Test consultation\nmulti update " + number, "Administrator");
			});
		}
		executor.shutdown();
		executor.awaitTermination(5, TimeUnit.SECONDS);
		assertEquals(100, encounter.getBilled().size());
		assertTrue(encounter.getVersionedEntry().getHeadVersion() > 1);
		// IEncounterService#updateVersionedEntry is not thread save but better than direct modify without refresh ...
		// enable if there is some locking to ensure thread safety
		// assertEquals(99, encounter.getVersionedEntry().getHeadVersion());
		
		IQuery<ICustomService> query = coreModelService.getQuery(ICustomService.class);
		for (ICustomService service : query.execute()) {
			coreModelService.remove(service);
		}
	}
}

@@ -292,33 +292,8 @@
 re;%0A
-import org.junit.Ignore;%0A
 impo
@@ -1011,50 +1011,8 @@
 %7D%0A%09%0A
-%09@Ignore(%22race condtion on build server%22)%0A
 %09@Te

Revert "[22480] ignore multiThreadUpdate test, race condtion on build"