package uk.ac.ebi.quickgo.geneproduct.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import uk.ac.ebi.quickgo.geneproduct.model.GeneProduct;
import uk.ac.ebi.quickgo.geneproduct.service.GeneProductService;
import uk.ac.ebi.quickgo.rest.ResponseExceptionHandler;
import uk.ac.ebi.quickgo.rest.search.ControllerHelper;
import uk.ac.ebi.quickgo.rest.search.ControllerHelperImpl;
import uk.ac.ebi.quickgo.rest.search.results.QueryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author Tony Wardell
 * Date: 29/03/2016
 * Time: 10:09
 *
 * Provides RESTful endpoints for retrieving Gene Product Information
 *
 * Created with IntelliJ IDEA.
 */
@RestController
@RequestMapping(value = "/QuickGO/services/geneproduct")
public class GeneProductController {

	private final Logger LOGGER = LoggerFactory.getLogger(GeneProductController.class);
	static final int MAX_PAGE_RESULTS = 100;
//	private static final String RESOURCE_PATH = "geneproducts";

	private final ControllerHelper controllerHelper;
	private final GeneProductService geneProductService;

	@Autowired
	public GeneProductController(GeneProductService gpService, ControllerHelper controllerHelper) {
		Objects.requireNonNull(gpService, "The GeneProductService instance passed to the constructor of " +
				"GeneProductController should not be null.");
		Objects.requireNonNull(controllerHelper, "The ControllerHelper instance passed to the constructor of " +
				"GeneProductController should not be null.");
		this.geneProductService = gpService;
		this.controllerHelper = controllerHelper;
	}

	/**
	 * An empty or unknown path should result in a bad request
	 *
	 * @return a 400 response
	 */
//	@RequestMapping(value = "/*", produces = {MediaType.APPLICATION_JSON_VALUE})
//	public ResponseEntity<ResponseExceptionHandler.ErrorInfo> emptyId() {
//		throw new IllegalArgumentException("The requested end-point does not exist.");
//	}


	/**
	 * Get core information about a list of gene products in comma-separated-value (CSV) format
	 *
	 * @param ids gene product identifiers in CSV format
	 * @return
	 * <ul>
	 *     <li>all ids are valid: response consists of a 200 with the chosen information about the ontology terms</li>
	 *     <li>any id is not found: response returns 404</li>
	 *     <li>any id is of the an invalid format: response returns 400</li>
	 * </ul>
	 */
	@RequestMapping(value = "/{ids:,*}", produces = {MediaType.APPLICATION_JSON_VALUE})
	public ResponseEntity<QueryResult<GeneProduct>> findById(@PathVariable String[] ids) {
		validateRequestedResults(ids.length);
		return getGeneProductResponse(geneProductService.findById(ids));
	}


	/**
	 * Creates a {@link ResponseEntity} containing a {@link QueryResult} for a list of documents.
	 *
	 * @param docList a list of results
	 * @return a {@link ResponseEntity} containing a {@link QueryResult} for a list of documents
	 */
	protected ResponseEntity<QueryResult<GeneProduct>> getGeneProductResponse(List<GeneProduct> docList) {
		List<GeneProduct> resultsToShow;
		if (docList == null) {
			resultsToShow = Collections.emptyList();
		} else {
			resultsToShow = docList;
		}

		QueryResult<GeneProduct> queryResult = new QueryResult<>(resultsToShow.size(), resultsToShow, null, null, null);
		return new ResponseEntity<>(queryResult, HttpStatus.OK);
	}



	/**
	 * Checks whether the requested number of results is valid.
	 * @param requestedResultsSize the number of results being requested
	 * @throws IllegalArgumentException if the number is greater than {@link #MAX_PAGE_RESULTS}
	 */
	protected void validateRequestedResults(int requestedResultsSize) {
		if (requestedResultsSize > MAX_PAGE_RESULTS) {
			String errorMessage = "Cannot retrieve more than " + MAX_PAGE_RESULTS + " results in one request. " +
					"Please consider using end-points that return paged results.";
			LOGGER.error(errorMessage);
			throw new IllegalArgumentException(errorMessage);
		}
	}


	/**
	 * Checks the validity of a geneproduct id.
	 *
	 * @param id the term id to check
	 * @throws IllegalArgumentException is thrown if the ID is not valid
	 */
	protected void checkValidId(String id) {
		if (!isValidId(id)) {
			throw new IllegalArgumentException("Provided ID: '" + id + "' is invalid");
		}
	}

	/**
	 * Are there any requirements for the validity of a gene product id
	 * @param id
	 * @return
	 */
	protected boolean isValidId(String id) {
		return true;
	}


}

@@ -857,93 +857,9 @@
 til.
-Arrays;%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.Objects
+*
 ;%0A%0A/
@@ -3359,20 +3359,35 @@
 st) %7B%0A%09%09
-List
+QueryResult.Builder
 %3CGenePro
@@ -3392,29 +3392,23 @@
 roduct%3E 
-resultsToShow
+builder
 ;%0A%09%09if (
@@ -3429,31 +3429,54 @@
 l) %7B%0A%09%09%09
-resultsToShow =
+builder = new QueryResult.Builder%3C%3E(0,
  Collect
@@ -3491,16 +3491,17 @@
 tyList()
+)
 ;%0A%09%09%7D el
@@ -3509,155 +3509,77 @@
 e %7B%0A
+ 
 %09%09%09
-resultsToShow = docList;%0A%09%09%7D%0A%0A%09%09QueryResult%3CGeneProduct%3E queryResult = new QueryResult%3C%3E(resultsToShow.size(), resultsToShow, null, null, null);
+builder = new QueryResult.Builder%3C%3E(docList.size(), docList);%0A%09%09%7D
 %0A%09%09r
@@ -3609,19 +3609,23 @@
 y%3C%3E(
-queryResult
+builder.build()
 , Ht

Use QueryResult.Builder.