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// SystemHooksService handles communication with the system hooks related
26// methods of the GitLab API.
27//
28// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
29type SystemHooksService struct {
30	client *Client
31}
32
33// Hook represents a GitLap system hook.
34//
35// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
36type Hook struct {
37	ID        int        `json:"id"`
38	URL       string     `json:"url"`
39	CreatedAt *time.Time `json:"created_at"`
40}
41
42func (h Hook) String() string {
43	return Stringify(h)
44}
45
46// ListHooks gets a list of system hooks.
47//
48// GitLab API docs:
49// https://docs.gitlab.com/ce/api/system_hooks.html#list-system-hooks
50func (s *SystemHooksService) ListHooks(options ...RequestOptionFunc) ([]*Hook, *Response, error) {
51	req, err := s.client.NewRequest(http.MethodGet, "hooks", nil, options)
52	if err != nil {
53		return nil, nil, err
54	}
55
56	var h []*Hook
57	resp, err := s.client.Do(req, &h)
58	if err != nil {
59		return nil, resp, err
60	}
61
62	return h, resp, err
63}
64
65// AddHookOptions represents the available AddHook() options.
66//
67// GitLab API docs:
68// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook
69type AddHookOptions struct {
70	URL                    *string `url:"url,omitempty" json:"url,omitempty"`
71	Token                  *string `url:"token,omitempty" json:"token,omitempty"`
72	PushEvents             *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
73	TagPushEvents          *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
74	MergeRequestsEvents    *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
75	RepositoryUpdateEvents *bool   `url:"repository_update_events,omitempty" json:"repository_update_events,omitempty"`
76	EnableSSLVerification  *bool   `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
77}
78
79// AddHook adds a new system hook hook.
80//
81// GitLab API docs:
82// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook
83func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...RequestOptionFunc) (*Hook, *Response, error) {
84	req, err := s.client.NewRequest(http.MethodPost, "hooks", opt, options)
85	if err != nil {
86		return nil, nil, err
87	}
88
89	h := new(Hook)
90	resp, err := s.client.Do(req, h)
91	if err != nil {
92		return nil, resp, err
93	}
94
95	return h, resp, err
96}
97
98// HookEvent represents an event trigger by a GitLab system hook.
99//
100// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
101type HookEvent struct {
102	EventName  string `json:"event_name"`
103	Name       string `json:"name"`
104	Path       string `json:"path"`
105	ProjectID  int    `json:"project_id"`
106	OwnerName  string `json:"owner_name"`
107	OwnerEmail string `json:"owner_email"`
108}
109
110func (h HookEvent) String() string {
111	return Stringify(h)
112}
113
114// TestHook tests a system hook.
115//
116// GitLab API docs:
117// https://docs.gitlab.com/ce/api/system_hooks.html#test-system-hook
118func (s *SystemHooksService) TestHook(hook int, options ...RequestOptionFunc) (*HookEvent, *Response, error) {
119	u := fmt.Sprintf("hooks/%d", hook)
120
121	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
122	if err != nil {
123		return nil, nil, err
124	}
125
126	h := new(HookEvent)
127	resp, err := s.client.Do(req, h)
128	if err != nil {
129		return nil, resp, err
130	}
131
132	return h, resp, err
133}
134
135// DeleteHook deletes a system hook. This is an idempotent API function and
136// returns 200 OK even if the hook is not available. If the hook is deleted it
137// is also returned as JSON.
138//
139// GitLab API docs:
140// https://docs.gitlab.com/ce/api/system_hooks.html#delete-system-hook
141func (s *SystemHooksService) DeleteHook(hook int, options ...RequestOptionFunc) (*Response, error) {
142	u := fmt.Sprintf("hooks/%d", hook)
143
144	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
145	if err != nil {
146		return nil, err
147	}
148
149	return s.client.Do(req, nil)
150}
151