package com.namelessmc.java_api;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.namelessmc.java_api.exception.NamelessException;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.*;

public class FilteredUserListBuilder {

	private final @NonNull NamelessAPI api;
	private @Nullable Map<UserFilter<?>, Object> filters;
	private @NonNull String operator = "AND";

	FilteredUserListBuilder(@NonNull NamelessAPI api) {
		this.api = api;
	}

	public <T> @NonNull FilteredUserListBuilder withFilter(final @NonNull UserFilter<T> filter,
														   final @NonNull T value) {
		if (filters == null) {
			filters = new HashMap<>();
		}

		filters.put(
				Objects.requireNonNull(filter, "Filter is null"),
				Objects.requireNonNull(value, "Value for filter " + filter.name() + " is null")
		);
		return this;
	}

	public @NonNull FilteredUserListBuilder all() {
		this.operator = "AND";
		return this;
	}

	public @NonNull FilteredUserListBuilder any() {
		this.operator = "OR";
		return this;
	}

	public JsonObject makeRawRequest() throws NamelessException {
		final Object[] parameters;
		if (filters != null) {
			int filterCount = filters.size();
			parameters = new Object[filterCount * 2 + 2];
			parameters[0] = "operator";
			parameters[1] = operator;
			int i = 2;
			for (Map.Entry<UserFilter<?>, Object> filter : this.filters.entrySet()) {
				parameters[i++] = filter.getKey().name();
				parameters[i++] = filter.getValue();
			}
		} else {
			parameters = new Object[0];
		}

		return this.api.requests().get("users", parameters);
	}

	public @NonNull List<@NonNull NamelessUser> makeRequest() throws NamelessException {
		final JsonObject response = this.makeRawRequest();
		final JsonArray array = response.getAsJsonArray("users");
		final List<NamelessUser> users = new ArrayList<>(array.size());
		for (final JsonElement e : array) {
			final JsonObject o = e.getAsJsonObject();
			final int id = o.get("id").getAsInt();
			users.add(new NamelessUser(this.api, id));
		}
		return Collections.unmodifiableList(users);
	}

}

package com.namelessmc.java_api;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.namelessmc.java_api.exception.NamelessException;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.*;

public class FilteredUserListBuilder {

	private final @NonNull NamelessAPI api;
	private @Nullable Map<UserFilter<?>, Object> filters;
	private @NonNull String operator = "AND";

	FilteredUserListBuilder(@NonNull NamelessAPI api) {
		this.api = api;
	}

	public <T> @NonNull FilteredUserListBuilder withFilter(final @NonNull UserFilter<T> filter,
														   final @NonNull T value) {
		if (filters == null) {
			filters = new HashMap<>();
		}

		filters.put(
				Objects.requireNonNull(filter, "Filter is null"),
				Objects.requireNonNull(value, "Value for filter " + filter.name() + " is null")
		);
		return this;
	}

	public @NonNull FilteredUserListBuilder all() {
		this.operator = "AND";
		return this;
	}

	public @NonNull FilteredUserListBuilder any() {
		this.operator = "OR";
		return this;
	}

	public JsonObject makeRawRequest() throws NamelessException {
		final Object[] parameters;
		if (filters != null) {
			int filterCount = filters.size();
			parameters = new Object[4 + filterCount * 2];
			int i = 0;
			parameters[i++] = "operator";
			parameters[i++] = operator;
			parameters[i++] = "limit";
			parameters[i++] = 0;
			for (Map.Entry<UserFilter<?>, Object> filter : this.filters.entrySet()) {
				parameters[i++] = filter.getKey().name();
				parameters[i++] = filter.getValue();
			}
		} else {
			parameters = new Object[0];
		}

		return this.api.requests().get("users", parameters);
	}

	public @NonNull List<@NonNull NamelessUser> makeRequest() throws NamelessException {
		final JsonObject response = this.makeRawRequest();
		final JsonArray array = response.getAsJsonArray("users");
		final List<NamelessUser> users = new ArrayList<>(array.size());
		for (final JsonElement e : array) {
			final JsonObject o = e.getAsJsonObject();
			final int id = o.get("id").getAsInt();
			users.add(new NamelessUser(this.api, id));
		}
		return Collections.unmodifiableList(users);
	}

}

disable user list limit, we don't support it