package ca.uhn.fhir.jpa.dao.r4;

import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.HasParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.ListResource;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import java.util.List;

import static ca.uhn.fhir.rest.api.Constants.PARAM_HAS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;

public class FhirResourceDaoSearchListTest extends BaseJpaR4Test {
	@Autowired
	@Qualifier("myListDaoR4")
	protected IFhirResourceDao<ListResource> myListResourceDao;

	/**
	 * See https://www.hl7.org/fhir/search.html#list
	 */
	@Test
	public void testList() {
		Patient patient1 = new Patient();
		Patient patient2 = new Patient();
		IIdType pid1 = myPatientDao.create(patient1).getId();
		IIdType pid2 = myPatientDao.create(patient2).getId();
		ListResource list = new ListResource();
		list.addEntry().getItem().setReferenceElement(pid1);
		list.addEntry().getItem().setReferenceElement(pid2);
		String listIdString = myListResourceDao.create(list).getId().getValue();

		{
			// What we need to emulate
			// /Patient?_has=List:item:_id=123
			SearchParameterMap map = SearchParameterMap.newSynchronous();
			// 	public HasParam(String theTargetResourceType, String theReferenceFieldName, String theParameterName, String theParameterValue) {
			map.add(PARAM_HAS, new HasParam("List", "item", "_id", listIdString));
			IBundleProvider bundle = myPatientDao.search(map);
			List<IBaseResource> resources = bundle.getResources(0, 2);
			assertThat(resources, hasSize(2));
		}

		{
			// The new syntax
			SearchParameterMap map = SearchParameterMap.newSynchronous();
			map.add("_list", new StringParam(listIdString));
			IBundleProvider bundle = myPatientDao.search(map);
			List<IBaseResource> resources = bundle.getResources(0, 2);
			assertThat(resources, hasSize(2));
			// assert ids equal pid1 and pid2
		}
	}
}

@@ -75,16 +75,68 @@
 rceDao;%0A
+import ca.uhn.fhir.jpa.searchparam.MatchUrlService;%0A
 import c
@@ -182,16 +182,16 @@
 terMap;%0A
-
 import c
@@ -278,51 +278,8 @@
 am;%0A
-import ca.uhn.fhir.rest.param.StringParam;%0A
 impo
@@ -964,16 +964,72 @@
 urceDao;
+%0A%09@Autowired%0A%09private MatchUrlService myMatchUrlService;
 %0A%0A%09/**%0A%09
@@ -2058,16 +2058,65 @@
  syntax%0A
+%09%09%09String queryString = %22_list=%22 + listIdString;%0A
 %09%09%09Searc
@@ -2139,93 +2139,95 @@
 p = 
-SearchParame
+myMatchUrlService.transla
 te
-r
 Ma
-p.newSynchronous();%0A%09%09%09map.add(%22_list%22, new StringParam(listIdString
+tchUrl(queryString, myFhirCtx.getResourceDefinition(%22List%22
 ));%0A
@@ -2421,13 +2421,70 @@
 id2%0A%09%09%7D%0A
-
 %09%7D
+%0A%0A%09// FIXME KH test other cases like _list=12,13&_list=14
 %0A%7D%0A

test infrastructure