package uk.ac.ebi.quickgo.annotation.model;

import uk.ac.ebi.quickgo.annotation.common.document.AnnotationFields;
import uk.ac.ebi.quickgo.annotation.validation.AnnotationValidation;
import uk.ac.ebi.quickgo.rest.search.query.FilterProvider;
import uk.ac.ebi.quickgo.rest.search.query.PrototypeFilter;
import uk.ac.ebi.quickgo.rest.search.query.Validator;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.stream.Stream;
import org.springframework.validation.Errors;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
 * A data structure for the annotation filtering parameters passed in from the client.
 *
 * Once the comma separated values have been set, then turn then into an object (PrototypeFilter) that
 * encapsulates the list and solr field name to use for that argument.
 *
 * @author Tony Wardell
 * Date: 25/04/2016
 * Time: 11:23
 * Created with IntelliJ IDEA.
 */
public class AnnotationFilter implements FilterProvider {

    public static final String DEFAULT_ENTRIES_PER_PAGE = "25";
    private static final String DEFAULT_PAGE_NUMBER = "1";

    //Non-data parameters
    private String limit = DEFAULT_ENTRIES_PER_PAGE;
    private String page = DEFAULT_PAGE_NUMBER;

    private final List<PrototypeFilter> prototypeFilters = new ArrayList<>();



    // E.g. ASPGD,Agbase,..
    public void setAssignedBy(String assignedBy) {

        if (!isNullOrEmpty(assignedBy)) {

            final Validator<String> validator = (String s) -> {
                Matcher m = AnnotationValidation.ALL_NUMERIC.matcher(s);
                if (m.matches()) {
                    throw new IllegalArgumentException("Values for assignedBy cannot be fully numeric");
                }
            };

            final PrototypeFilter pFilter = PrototypeFilter.create(AnnotationFields.ASSIGNED_BY, assignedBy, validator);
            prototypeFilters.add(pFilter);
        }

    }



    public void setPage(String page) {
        this.page = page;
    }

    public void setLimit(String limit) {
        this.limit = limit;
    }

    public int getLimit() {
        return Integer.parseInt(limit);
    }

    public int getPage() {
        return Integer.parseInt(page);
    }

    public Stream<PrototypeFilter> stream() {
        return prototypeFilters.stream();
    }

}

@@ -351,16 +351,61 @@
 dator;%0A%0A
+import com.google.common.base.Preconditions;%0A
 import j
@@ -1059,38 +1059,35 @@
 ic static final 
-Str
 in
-g
+t
  DEFAULT_ENTRIES
@@ -1102,12 +1102,10 @@
 E = 
-%22
 25
-%22
 ;%0A  
@@ -1127,22 +1127,19 @@
 c final 
-Str
 in
-g
+t
  DEFAULT
@@ -1157,11 +1157,9 @@
 R = 
-%221%22
+1
 ;%0A%0A 
@@ -1195,22 +1195,20 @@
 private 
-String
+int 
  limit =
@@ -1246,22 +1246,19 @@
 private 
-Str
 in
-g
+t
  page = 
@@ -2006,96 +2006,266 @@
 age(
-String page) %7B%0A        this.page = page;%0A    %7D%0A%0A    public void setLimit(String limit) %7B
+int page) %7B%0A        Preconditions.checkArgument(page%3E-1, %22The value for page cannot be negative%22);%0A        this.page = page;%0A    %7D%0A%0A    public void setLimit(int limit) %7B%0A        Preconditions.checkArgument(limit%3E-1, %22The value for limit cannot be negative%22);
 %0A   
@@ -2343,31 +2343,13 @@
 urn 
-Integer.parseInt(
 limit
-)
 ;%0A  
@@ -2399,30 +2399,12 @@
 urn 
-Integer.parseInt(
 page
-)
 ;%0A  

Check for negative values for page and limit.