/*
 * Copyright 2021 B2i Healthcare Pte Ltd, http://b2i.sg
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.b2international.snowowl.core.rest.suggestion;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.bind.annotation.*;

import com.b2international.snowowl.core.codesystem.CodeSystemRequests;
import com.b2international.snowowl.core.domain.Suggestions;
import com.b2international.snowowl.core.events.util.Promise;
import com.b2international.snowowl.core.request.SearchIndexResourceRequest;
import com.b2international.snowowl.core.request.SearchResourceRequest.SortField;
import com.b2international.snowowl.core.rest.AbstractRestService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * @since 8.0
 */
@Tag(description = "Suggestion", name = "suggestion")
@RestController
@RequestMapping(value = "/suggestion", produces = { AbstractRestService.JSON_MEDIA_TYPE })
public class SuggestionRestService extends AbstractRestService {
	
	private static final int TOP_TOKEN_COUNT = 3;
	private static final int MIN_OCCURRENCE_COUNT = 1;
	
	private static final SortField SORT_BY = SearchIndexResourceRequest.SCORE;
	
	@Operation(
		summary = "Concept suggestion", 
		description = "Returns an actual concept of the specified code system based on the source term.")
	@ApiResponses({ 
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "400", description = "Bad Request") 
	})
	@GetMapping
	public Promise<Suggestions> getSuggestion(@ParameterObject final SuggestionRestParameters params) {
		return CodeSystemRequests.prepareSuggestConcepts()
				.setLimit(params.getLimit())
				.setTopTokenCount(TOP_TOKEN_COUNT)
				.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)
				.setPreferredDisplay(params.getPreferredDisplay())
				.filterByTerm(params.getTerm())
				.sortBy(SORT_BY)
				.build(params.getCodeSystemPath())
				.execute(getBus());
	}
	
	@Operation(
			summary = "Concept suggestion", 
			description = "Returns an actual concept of the specified code system based on the source term.")
	@ApiResponses({ 
		@ApiResponse(responseCode = "201", description = "OK"),
		@ApiResponse(responseCode = "400", description = "Bad Request") 
	})
	@PostMapping
	public Promise<Suggestions> postSuggestion(@RequestBody final SuggestionRestParameters body) {
		return CodeSystemRequests.prepareSuggestConcepts()
				.setLimit(body.getLimit())
				.setTopTokenCount(TOP_TOKEN_COUNT)
				.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)
				.setPreferredDisplay(body.getPreferredDisplay())
				.filterByTerm(body.getTerm())
				.sortBy(SORT_BY)
				.build(body.getCodeSystemPath())
				.execute(getBus());
	}
	
	@Operation(
		summary = "Bulk concept suggestion", 
		description = "Perform a bulk suggestion request.")
	@ApiResponses({ 
		@ApiResponse(responseCode = "201", description = "OK"),
		@ApiResponse(responseCode = "400", description = "Bad Request") 
	})
	@PostMapping(value = "/bulk")
	public List<Suggestions> postBulkSuggestion(@RequestBody final List<SuggestionRestParameters> body) {
		return body.stream().map(params -> {
			return CodeSystemRequests.prepareSuggestConcepts()
				.setLimit(params.getLimit())
				.setTopTokenCount(TOP_TOKEN_COUNT)
				.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)
				.setPreferredDisplay(params.getPreferredDisplay())
				.filterByTerm(params.getTerm())
				.sortBy(SORT_BY)
				.build(params.getCodeSystemPath())
				.execute(getBus())
				.getSync(COMMIT_TIMEOUT, TimeUnit.MINUTES);
		})
		.collect(Collectors.toList());
	}
}

@@ -702,46 +702,8 @@
 st;%0A
-import java.util.concurrent.TimeUnit;%0A
 impo
@@ -1522,19 +1522,16 @@
 %22Suggest
-ion
 %22, name 
@@ -1540,19 +1540,16 @@
 %22suggest
-ion
 %22)%0A@Rest
@@ -1592,19 +1592,16 @@
 /suggest
-ion
 %22, produ
@@ -1718,109 +1718,8 @@
 %7B%0A%09%0A
-%09private static final int TOP_TOKEN_COUNT = 3;%0A%09private static final int MIN_OCCURRENCE_COUNT = 1;%0A%09%0A
 %09pri
@@ -1948,33 +1948,32 @@
 %09@ApiResponses(%7B
- 
 %0A%09%09@ApiResponse(
@@ -2290,96 +2290,8 @@
 ())%0A
-%09%09%09%09.setTopTokenCount(TOP_TOKEN_COUNT)%0A%09%09%09%09.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)%0A
 %09%09%09%09
@@ -2961,96 +2961,8 @@
 ())%0A
-%09%09%09%09.setTopTokenCount(TOP_TOKEN_COUNT)%0A%09%09%09%09.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)%0A
 %09%09%09%09
@@ -3428,24 +3428,28 @@
 lic 
-List%3CSuggestions
+Promise%3CList%3CObject%3E
 %3E po
@@ -3525,22 +3525,59 @@
 dy) %7B%0A%09%09
-return
+final List%3CPromise%3CSuggestions%3E%3E promises =
  body.st
@@ -3690,96 +3690,8 @@
 ())%0A
-%09%09%09%09.setTopTokenCount(TOP_TOKEN_COUNT)%0A%09%09%09%09.setMinOccurrenceCount(MIN_OCCURRENCE_COUNT)%0A
 %09%09%09%09
@@ -3863,64 +3863,14 @@
 s())
-%0A%09%09%09%09.getSync(COMMIT_TIMEOUT, TimeUnit.MINUTES)
 ;%0A%09%09%7D)
-%0A%09%09
 .col
@@ -3896,13 +3896,48 @@
 ist());%0A
+%09%09%0A%09%09return Promise.all(promises);%0A
 %09%7D%0A%7D%0A

rename mapping and fix bulk endpoint