001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.users;
017
018import com.fasterxml.jackson.annotation.JsonValue;
019import com.vonage.client.QueryParamsRequest;
020import com.vonage.client.common.HalLinks;
021import java.net.URI;
022import java.util.LinkedHashMap;
023import java.util.Map;
024
025/**
026 * Query parameters for {@link UsersClient#listUsers(ListUsersRequest)}.
027 */
028public final class ListUsersRequest implements QueryParamsRequest {
029    private final int pageSize;
030    private final SortOrder order;
031    private final String name, cursor;
032
033    private ListUsersRequest(Builder builder) {
034        if ((pageSize = builder.pageSize) < 1 || pageSize > 100) {
035            throw new IllegalArgumentException("Page size must be between 1 and 100.");
036        }
037        order = builder.order;
038        name = builder.name;
039        cursor = parseCursor(builder.cursor);
040    }
041
042    static String parseCursor(URI cursor) {
043        if (cursor == null) return null;
044        String query = cursor.getRawQuery();
045        return query.substring(query.indexOf("cursor=") + 7);
046    }
047
048    @Override
049    public Map<String, String> makeParams() {
050        LinkedHashMap<String, String> params = new LinkedHashMap<>(4);
051        params.put("page_size", String.valueOf(pageSize));
052        if (order != null) {
053            params.put("order", order.toString());
054        }
055        if (name != null) {
056            params.put("name", name);
057        }
058        if (cursor != null) {
059            params.put("cursor", cursor);
060        }
061        return params;
062    }
063
064    /**
065     * Number of records to return in the response. Default is 10.
066     *
067     * @return The number of results to return.
068     */
069    public int getPageSize() {
070        return pageSize;
071    }
072
073    /**
074     * The time order to return results in. Default is ascending.
075     *
076     * @return The order to return results in as an enum.
077     */
078    public SortOrder getOrder() {
079        return order;
080    }
081
082    /**
083     * Unique name for a user to filter by.
084     *
085     * @return The username to search for, or {@code null} if not specified.
086     */
087    public String getName() {
088        return name;
089    }
090
091    /**
092     * The cursor to start returning results from, as derived from the {@code _links} section of a response.
093     *
094     * @return The cursor key to search from, or {@code null} if not specified.
095     */
096    public String getCursor() {
097        return cursor;
098    }
099
100    /**
101     * Entry point for constructing an instance of this class.
102     *
103     * @return A new Builder.
104     */
105    public static Builder builder() {
106        return new Builder();
107    }
108
109    public static class Builder {
110        private int pageSize = 10;
111        private SortOrder order = SortOrder.ASC;
112        private String name;
113        private URI cursor;
114
115        Builder() {}
116
117        /**
118         * Number of records to return in the response. Maximum is 100, default is 10.
119         *
120         * @param pageSize Number of results to return.
121         *
122         * @return This builder.
123         */
124        public Builder pageSize(int pageSize) {
125            this.pageSize = pageSize;
126            return this;
127        }
128
129        /**
130         * The order to return the results in. Users are sorted by their creation time.
131         * Default is ascending - i.e. newest to oldest. Use {@linkplain SortOrder#DESC} to sort
132         * the results from oldest to newest.
133         *
134         * @param order The sort order for results as an enum.
135         *
136         * @return This builder.
137         */
138        public Builder order(SortOrder order) {
139            this.order = order;
140            return this;
141        }
142
143        /**
144         * Find user by their name.
145         *
146         * @param name Unique user name.
147         *
148         * @return This builder.
149         */
150        public Builder name(String name) {
151            this.name = name;
152            return this;
153        }
154
155        /**
156         * The cursor to start returning results from.<br>
157         *
158         * You are not expected to provide this manually. Instead, this will be parsed from the response
159         * page's links. You need to provide the URL of the page. This can be obtained from
160         * {@link ListUsersResponse#getLinks()}, on which you would then call either
161         * {@linkplain HalLinks#getNextUrl()} or {@linkplain HalLinks#getPrevUrl()} and pass it to this method.
162         *
163         * @param cursor Page link URL containing the "cursor" query parameter.
164         *
165         * @return This builder.
166         */
167        public Builder cursor(URI cursor) {
168            this.cursor = cursor;
169            return this;
170        }
171
172        /**
173         * Builds the request.
174         *
175         * @return A new ListUsersRequest with this builder's properties.
176         */
177        public ListUsersRequest build() {
178            return new ListUsersRequest(this);
179        }
180    }
181
182    /**
183     * Represents the sort order for events.
184     */
185    public enum SortOrder {
186        /**
187         * Ascending
188         */
189        ASC,
190
191        /**
192         * Descending
193         */
194        DESC;
195
196        @JsonValue
197        @Override
198        public String toString() {
199            return name().toLowerCase();
200        }
201    }
202}