// Copyright (c) 2017, Worcade. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package net.worcade.client.internal;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.ToString;
import net.worcade.client.query.EntityField;
import net.worcade.client.query.Query;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

@AllArgsConstructor(access = AccessLevel.PACKAGE) @ToString
public class WorcadeQuery<T extends EntityField> implements Query<T> {
    private final Set<EntityField> fields;
    private final Multimap<EntityField, String> filter;
    private final List<Order> order;
    private final int limit;

    String toQueryString() {
        StringBuilder sb = new StringBuilder("?limit=" + limit);
        for (EntityField field : fields) {
            sb.append("&field=").append(field.name());
        }
        for (Map.Entry<? extends EntityField, String> filter : filter.entries()) {
            sb.append("&").append(filter.getKey().name()).append("=").append(Util.escapeUrlQueryParameter(filter.getValue()));
        }
        for (Order o : order) {
            sb.append("&order=").append(o.ascending ? "" : "-").append(o.field.name());
        }
        return sb.toString();
    }

    public static <T extends Enum<T> & EntityField> Query.Builder<T> builder() {
        return new Builder<>();
    }

    static class Builder<T extends Enum<T> & EntityField> implements Query.Builder<T> {
        final Set<EntityField> fields = Sets.newHashSet();
        final ImmutableMultimap.Builder<EntityField, String> filter = ImmutableMultimap.builder();
        final ImmutableList.Builder<Order> order = ImmutableList.builder();
        int limit = 10;

        @Override
        @SafeVarargs
        public final Builder<T> fields(T... fields) {
            Collections.addAll(this.fields, fields);
            return this;
        }

        @Override
        public Builder<T> fields(Collection<T> fields) {
            this.fields.addAll(fields);
            return this;
        }

        @Override
        public Builder<T> filter(T field, String value) {
            filter.put(field, value);
            return this;
        }

        @Override
        public Builder<T> order(T field, boolean ascending) {
            order.add(new Order(field, ascending));
            return this;
        }

        @Override
        public Builder<T> limit(int limit) {
            this.limit = Math.min(Math.max(1, limit), 100);
            return this;
        }

        @Override
        public WorcadeQuery<T> build() {
            return new WorcadeQuery<>(ImmutableSet.copyOf(fields), filter.build(), order.build(), limit);
        }
    }

    @AllArgsConstructor(access = AccessLevel.PRIVATE) @ToString
    static class Order {
        private final EntityField field;
        private final boolean ascending;
    }
}

@@ -230,16 +230,55 @@
 ernal;%0A%0A
+import com.google.common.base.Strings;%0A
 import c
@@ -1090,16 +1090,49 @@
 t limit;
+%0A    private final String search;
 %0A%0A    St
@@ -1669,32 +1669,168 @@
 e());%0A        %7D%0A
+        if (!Strings.isNullOrEmpty(search)) %7B%0A            sb.append(%22&search=%22).append(Util.escapeUrlQueryParameter(search));%0A        %7D%0A
         return s
@@ -1970,24 +1970,32 @@
 %0A    %7D%0A%0A    
+private 
 static class
@@ -2070,24 +2070,32 @@
 %3E %7B%0A        
+private 
 final Set%3CEn
@@ -2133,32 +2133,40 @@
 hSet();%0A        
+private 
 final ImmutableM
@@ -2248,16 +2248,24 @@
         
+private 
 final Im
@@ -2332,16 +2332,24 @@
         
+private 
 int limi
@@ -2355,16 +2355,47 @@
 it = 10;
+%0A        private String search;
 %0A%0A      
@@ -3190,32 +3190,171 @@
 his;%0A        %7D%0A%0A
+        @Override%0A        public Builder%3CT%3E search(String search) %7B%0A            this.search = search;%0A            return this;%0A        %7D%0A%0A%0A
         @Overrid
@@ -3495,24 +3495,32 @@
 ild(), limit
+, search
 );%0A        %7D

Implement search parameter in list queries