1//
2// Copyright 2021, Sander van Harmelen
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17package gitlab
18
19import (
20	"fmt"
21	"net/http"
22	"time"
23)
24
25// IssuesStatisticsService handles communication with the issues statistics
26// related methods of the GitLab API.
27//
28// GitLab API docs: https://docs.gitlab.com/ee/api/issues_statistics.html
29type IssuesStatisticsService struct {
30	client *Client
31}
32
33// IssuesStatistics represents a GitLab issues statistic.
34//
35// GitLab API docs: https://docs.gitlab.com/ee/api/issues_statistics.html
36type IssuesStatistics struct {
37	Statistics struct {
38		Counts struct {
39			All    int `json:"all"`
40			Closed int `json:"closed"`
41			Opened int `json:"opened"`
42		} `json:"counts"`
43	} `json:"statistics"`
44}
45
46func (n IssuesStatistics) String() string {
47	return Stringify(n)
48}
49
50// GetIssuesStatisticsOptions represents the available GetIssuesStatistics() options.
51//
52// GitLab API docs:
53// https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
54type GetIssuesStatisticsOptions struct {
55	Labels           Labels     `url:"labels,omitempty" json:"labels,omitempty"`
56	Milestone        *string    `url:"milestone,omitempty" json:"milestone,omitempty"`
57	Scope            *string    `url:"scope,omitempty" json:"scope,omitempty"`
58	AuthorID         *int       `url:"author_id,omitempty" json:"author_id,omitempty"`
59	AuthorUsername   *string    `url:"author_username,omitempty" json:"author_username,omitempty"`
60	AssigneeID       *int       `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
61	AssigneeUsername []string   `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
62	MyReactionEmoji  *string    `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
63	IIDs             []int      `url:"iids[],omitempty" json:"iids,omitempty"`
64	Search           *string    `url:"search,omitempty" json:"search,omitempty"`
65	In               *string    `url:"in,omitempty" json:"in,omitempty"`
66	CreatedAfter     *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
67	CreatedBefore    *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
68	UpdatedAfter     *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
69	UpdatedBefore    *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
70	Confidential     *bool      `url:"confidential,omitempty" json:"confidential,omitempty"`
71}
72
73// GetIssuesStatistics gets issues statistics on all issues the authenticated
74// user has access to.
75//
76// GitLab API docs:
77// https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
78func (s *IssuesStatisticsService) GetIssuesStatistics(opt *GetIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) {
79	req, err := s.client.NewRequest(http.MethodGet, "issues_statistics", opt, options)
80	if err != nil {
81		return nil, nil, err
82	}
83
84	is := new(IssuesStatistics)
85	resp, err := s.client.Do(req, is)
86	if err != nil {
87		return nil, resp, err
88	}
89
90	return is, resp, err
91}
92
93// GetGroupIssuesStatisticsOptions represents the available GetGroupIssuesStatistics()
94// options.
95//
96// GitLab API docs:
97// https://docs.gitlab.com/ee/api/issues_statistics.html#get-group-issues-statistics
98type GetGroupIssuesStatisticsOptions struct {
99	Labels           Labels     `url:"labels,omitempty" json:"labels,omitempty"`
100	IIDs             []int      `url:"iids[],omitempty" json:"iids,omitempty"`
101	Milestone        *string    `url:"milestone,omitempty" json:"milestone,omitempty"`
102	Scope            *string    `url:"scope,omitempty" json:"scope,omitempty"`
103	AuthorID         *int       `url:"author_id,omitempty" json:"author_id,omitempty"`
104	AuthorUsername   *string    `url:"author_username,omitempty" json:"author_username,omitempty"`
105	AssigneeID       *int       `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
106	AssigneeUsername []string   `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
107	MyReactionEmoji  *string    `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
108	Search           *string    `url:"search,omitempty" json:"search,omitempty"`
109	CreatedAfter     *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
110	CreatedBefore    *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
111	UpdatedAfter     *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
112	UpdatedBefore    *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
113	Confidential     *bool      `url:"confidential,omitempty" json:"confidential,omitempty"`
114}
115
116// GetGroupIssuesStatistics gets issues count statistics for given group.
117//
118// GitLab API docs:
119// https://docs.gitlab.com/ee/api/issues_statistics.html#get-group-issues-statistics
120func (s *IssuesStatisticsService) GetGroupIssuesStatistics(gid interface{}, opt *GetGroupIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) {
121	group, err := parseID(gid)
122	if err != nil {
123		return nil, nil, err
124	}
125	u := fmt.Sprintf("groups/%s/issues_statistics", pathEscape(group))
126
127	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
128	if err != nil {
129		return nil, nil, err
130	}
131
132	is := new(IssuesStatistics)
133	resp, err := s.client.Do(req, is)
134	if err != nil {
135		return nil, resp, err
136	}
137
138	return is, resp, err
139}
140
141// GetProjectIssuesStatisticsOptions represents the available
142// GetProjectIssuesStatistics() options.
143//
144// GitLab API docs:
145// https://docs.gitlab.com/ee/api/issues_statistics.html#get-project-issues-statistics
146type GetProjectIssuesStatisticsOptions struct {
147	IIDs             []int      `url:"iids[],omitempty" json:"iids,omitempty"`
148	Labels           Labels     `url:"labels,omitempty" json:"labels,omitempty"`
149	Milestone        *Milestone `url:"milestone,omitempty" json:"milestone,omitempty"`
150	Scope            *string    `url:"scope,omitempty" json:"scope,omitempty"`
151	AuthorID         *int       `url:"author_id,omitempty" json:"author_id,omitempty"`
152	AuthorUsername   *string    `url:"author_username,omitempty" json:"author_username,omitempty"`
153	AssigneeID       *int       `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
154	AssigneeUsername []string   `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
155	MyReactionEmoji  *string    `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
156	Search           *string    `url:"search,omitempty" json:"search,omitempty"`
157	CreatedAfter     *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
158	CreatedBefore    *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
159	UpdatedAfter     *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
160	UpdatedBefore    *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
161	Confidential     *bool      `url:"confidential,omitempty" json:"confidential,omitempty"`
162}
163
164// GetProjectIssuesStatistics gets issues count statistics for given project.
165//
166// GitLab API docs:
167// https://docs.gitlab.com/ee/api/issues_statistics.html#get-project-issues-statistics
168func (s *IssuesStatisticsService) GetProjectIssuesStatistics(pid interface{}, opt *GetProjectIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) {
169	project, err := parseID(pid)
170	if err != nil {
171		return nil, nil, err
172	}
173	u := fmt.Sprintf("projects/%s/issues_statistics", pathEscape(project))
174
175	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
176	if err != nil {
177		return nil, nil, err
178	}
179
180	is := new(IssuesStatistics)
181	resp, err := s.client.Do(req, is)
182	if err != nil {
183		return nil, resp, err
184	}
185
186	return is, resp, err
187}
188