1package gerrit
2
3import (
4	"fmt"
5)
6
7// GroupsService contains Group related REST endpoints
8//
9// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html
10type GroupsService struct {
11	client *Client
12}
13
14// GroupAuditEventInfo entity contains information about an audit event of a group.
15type GroupAuditEventInfo struct {
16	// TODO Member AccountInfo OR GroupInfo `json:"member"`
17	Type string      `json:"type"`
18	User AccountInfo `json:"user"`
19	Date Timestamp   `json:"date"`
20}
21
22// GroupInfo entity contains information about a group.
23// This can be a Gerrit internal group, or an external group that is known to Gerrit.
24type GroupInfo struct {
25	ID          string           `json:"id"`
26	Name        string           `json:"name,omitempty"`
27	URL         string           `json:"url,omitempty"`
28	Options     GroupOptionsInfo `json:"options"`
29	Description string           `json:"description,omitempty"`
30	GroupID     int              `json:"group_id,omitempty"`
31	Owner       string           `json:"owner,omitempty"`
32	OwnerID     string           `json:"owner_id,omitempty"`
33	CreatedOn   *Timestamp       `json:"created_on,omitempty"`
34	Members     []AccountInfo    `json:"members,omitempty"`
35	Includes    []GroupInfo      `json:"includes,omitempty"`
36}
37
38// GroupInput entity contains information for the creation of a new internal group.
39type GroupInput struct {
40	Name         string `json:"name,omitempty"`
41	Description  string `json:"description,omitempty"`
42	VisibleToAll bool   `json:"visible_to_all,omitempty"`
43	OwnerID      string `json:"owner_id,omitempty"`
44}
45
46// GroupOptionsInfo entity contains options of the group.
47type GroupOptionsInfo struct {
48	VisibleToAll bool `json:"visible_to_all,omitempty"`
49}
50
51// GroupOptionsInput entity contains new options for a group.
52type GroupOptionsInput struct {
53	VisibleToAll bool `json:"visible_to_all,omitempty"`
54}
55
56// GroupsInput entity contains information about groups that should be included into a group or that should be deleted from a group.
57type GroupsInput struct {
58	OneGroup string   `json:"_one_group,omitempty"`
59	Groups   []string `json:"groups,omitempty"`
60}
61
62// ListGroupsOptions specifies the different options for the ListGroups call.
63//
64// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#list-groups
65type ListGroupsOptions struct {
66	// Group Options
67	// Options fields can be obtained by adding o parameters, each option requires more lookups and slows down the query response time to the client so they are generally disabled by default.
68	// Optional fields are:
69	//	INCLUDES: include list of directly included groups.
70	//	MEMBERS: include list of direct group members.
71	Options []string `url:"o,omitempty"`
72
73	// Check if a group is owned by the calling user
74	// By setting the option owned and specifying a group to inspect with the option q, it is possible to find out, if this group is owned by the calling user.
75	// If the group is owned by the calling user, the returned map contains this group. If the calling user doesn’t own this group an empty map is returned.
76	Owned string `url:"owned,omitempty"`
77	Group string `url:"q,omitempty"`
78
79	// Group Limit
80	// The /groups/ URL also accepts a limit integer in the n parameter. This limits the results to show n groups.
81	Limit int `url:"n,omitempty"`
82	// The /groups/ URL also accepts a start integer in the S parameter. The results will skip S groups from group list.
83	Skip int `url:"S,omitempty"`
84}
85
86// ListGroups lists the groups accessible by the caller.
87// This is the same as using the ls-groups command over SSH, and accepts the same options as query parameters.
88// The entries in the map are sorted by group name.
89//
90// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#list-groups
91func (s *GroupsService) ListGroups(opt *ListGroupsOptions) (*map[string]GroupInfo, *Response, error) {
92	u := "groups/"
93
94	u, err := addOptions(u, opt)
95	if err != nil {
96		return nil, nil, err
97	}
98
99	req, err := s.client.NewRequest("GET", u, nil)
100	if err != nil {
101		return nil, nil, err
102	}
103
104	v := new(map[string]GroupInfo)
105	resp, err := s.client.Do(req, v)
106	if err != nil {
107		return nil, resp, err
108	}
109
110	return v, resp, err
111}
112
113// GetGroup retrieves a group.
114//
115// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group
116func (s *GroupsService) GetGroup(groupID string) (*GroupInfo, *Response, error) {
117	u := fmt.Sprintf("groups/%s", groupID)
118	return s.getGroupInfoResponse(u)
119}
120
121// GetGroupDetail retrieves a group with the direct members and the directly included groups.
122//
123// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group-detail
124func (s *GroupsService) GetGroupDetail(groupID string) (*GroupInfo, *Response, error) {
125	u := fmt.Sprintf("groups/%s/detail", groupID)
126	return s.getGroupInfoResponse(u)
127}
128
129// getGroupInfoResponse retrieved a single GroupInfo Response for a GET request
130func (s *GroupsService) getGroupInfoResponse(u string) (*GroupInfo, *Response, error) {
131	req, err := s.client.NewRequest("GET", u, nil)
132	if err != nil {
133		return nil, nil, err
134	}
135
136	v := new(GroupInfo)
137	resp, err := s.client.Do(req, v)
138	if err != nil {
139		return nil, resp, err
140	}
141
142	return v, resp, err
143}
144
145// GetGroupName retrieves the name of a group.
146//
147// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group-name
148func (s *GroupsService) GetGroupName(groupID string) (string, *Response, error) {
149	u := fmt.Sprintf("groups/%s/name", groupID)
150	return getStringResponseWithoutOptions(s.client, u)
151}
152
153// GetGroupDescription retrieves the description of a group.
154//
155// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group-description
156func (s *GroupsService) GetGroupDescription(groupID string) (string, *Response, error) {
157	u := fmt.Sprintf("groups/%s/description", groupID)
158	return getStringResponseWithoutOptions(s.client, u)
159}
160
161// GetGroupOptions retrieves the options of a group.
162//
163// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group-options
164func (s *GroupsService) GetGroupOptions(groupID string) (*GroupOptionsInfo, *Response, error) {
165	u := fmt.Sprintf("groups/%s/options", groupID)
166
167	req, err := s.client.NewRequest("GET", u, nil)
168	if err != nil {
169		return nil, nil, err
170	}
171
172	v := new(GroupOptionsInfo)
173	resp, err := s.client.Do(req, v)
174	if err != nil {
175		return nil, resp, err
176	}
177
178	return v, resp, err
179}
180
181// GetGroupOwner retrieves the owner group of a Gerrit internal group.
182//
183// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-group-owner
184func (s *GroupsService) GetGroupOwner(groupID string) (*GroupInfo, *Response, error) {
185	u := fmt.Sprintf("groups/%s/owner", groupID)
186
187	req, err := s.client.NewRequest("GET", u, nil)
188	if err != nil {
189		return nil, nil, err
190	}
191
192	v := new(GroupInfo)
193	resp, err := s.client.Do(req, v)
194	if err != nil {
195		return nil, resp, err
196	}
197
198	return v, resp, err
199}
200
201// GetAuditLog gets the audit log of a Gerrit internal group.
202// The returned audit events are sorted by date in reverse order so that the newest audit event comes first.
203//
204// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#get-audit-log
205func (s *GroupsService) GetAuditLog(groupID string) (*[]GroupAuditEventInfo, *Response, error) {
206	u := fmt.Sprintf("groups/%s/log.audit", groupID)
207
208	req, err := s.client.NewRequest("GET", u, nil)
209	if err != nil {
210		return nil, nil, err
211	}
212
213	v := new([]GroupAuditEventInfo)
214	resp, err := s.client.Do(req, v)
215	if err != nil {
216		return nil, resp, err
217	}
218
219	return v, resp, err
220}
221
222// CreateGroup creates a new Gerrit internal group.
223// In the request body additional data for the group can be provided as GroupInput.
224//
225// As response the GroupInfo entity is returned that describes the created group.
226// If the group creation fails because the name is already in use the response is “409 Conflict”.
227//
228// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#create-group
229func (s *GroupsService) CreateGroup(groupID string, input *GroupInput) (*GroupInfo, *Response, error) {
230	u := fmt.Sprintf("groups/%s", groupID)
231
232	req, err := s.client.NewRequest("PUT", u, input)
233	if err != nil {
234		return nil, nil, err
235	}
236
237	v := new(GroupInfo)
238	resp, err := s.client.Do(req, v)
239	if err != nil {
240		return nil, resp, err
241	}
242
243	return v, resp, err
244}
245
246// RenameGroup renames a Gerrit internal group.
247// The new group name must be provided in the request body.
248//
249// As response the new group name is returned.
250// If renaming the group fails because the new name is already in use the response is “409 Conflict”.
251//
252// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#rename-group
253func (s *GroupsService) RenameGroup(groupID, name string) (*string, *Response, error) {
254	u := fmt.Sprintf("groups/%s/name", groupID)
255	input := struct {
256		Name string `json:"name"`
257	}{
258		Name: name,
259	}
260
261	req, err := s.client.NewRequest("PUT", u, input)
262	if err != nil {
263		return nil, nil, err
264	}
265
266	v := new(string)
267	resp, err := s.client.Do(req, v)
268	if err != nil {
269		return nil, resp, err
270	}
271
272	return v, resp, err
273}
274
275// SetGroupDescription sets the description of a Gerrit internal group.
276// The new group description must be provided in the request body.
277//
278// As response the new group description is returned.
279// If the description was deleted the response is “204 No Content”.
280//
281// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#set-group-description
282func (s *GroupsService) SetGroupDescription(groupID, description string) (*string, *Response, error) {
283	u := fmt.Sprintf("groups/%s/description", groupID)
284	input := struct {
285		Description string `json:"description"`
286	}{
287		Description: description,
288	}
289
290	req, err := s.client.NewRequest("PUT", u, input)
291	if err != nil {
292		return nil, nil, err
293	}
294
295	v := new(string)
296	resp, err := s.client.Do(req, v)
297	if err != nil {
298		return nil, resp, err
299	}
300
301	return v, resp, err
302}
303
304// DeleteGroupDescription deletes the description of a Gerrit internal group.
305//
306// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#delete-group-description
307func (s *GroupsService) DeleteGroupDescription(groupID string) (*Response, error) {
308	u := fmt.Sprintf("groups/%s/description'", groupID)
309	return s.client.DeleteRequest(u, nil)
310}
311
312// SetGroupOptions sets the options of a Gerrit internal group.
313// The new group options must be provided in the request body as a GroupOptionsInput entity.
314//
315// As response the new group options are returned as a GroupOptionsInfo entity.
316//
317// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#set-group-options
318func (s *GroupsService) SetGroupOptions(groupID string, input *GroupOptionsInput) (*GroupOptionsInfo, *Response, error) {
319	u := fmt.Sprintf("groups/%s/options", groupID)
320
321	req, err := s.client.NewRequest("PUT", u, input)
322	if err != nil {
323		return nil, nil, err
324	}
325
326	v := new(GroupOptionsInfo)
327	resp, err := s.client.Do(req, v)
328	if err != nil {
329		return nil, resp, err
330	}
331
332	return v, resp, err
333}
334
335// SetGroupOwner sets the owner group of a Gerrit internal group.
336// The new owner group must be provided in the request body.
337// The new owner can be specified by name, by group UUID or by the legacy numeric group ID.
338//
339// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#set-group-owner
340func (s *GroupsService) SetGroupOwner(groupID, owner string) (*GroupInfo, *Response, error) {
341	u := fmt.Sprintf("groups/%s/owner", groupID)
342	input := struct {
343		Owner string `json:"owner"`
344	}{
345		Owner: owner,
346	}
347
348	req, err := s.client.NewRequest("PUT", u, input)
349	if err != nil {
350		return nil, nil, err
351	}
352
353	v := new(GroupInfo)
354	resp, err := s.client.Do(req, v)
355	if err != nil {
356		return nil, resp, err
357	}
358
359	return v, resp, err
360}
361