1package domain
2
3import (
4	"fmt"
5	"github.com/transip/gotransip/v6"
6	"github.com/transip/gotransip/v6/repository"
7	"github.com/transip/gotransip/v6/rest"
8	"net/url"
9)
10
11// Repository can be used to get a list of your domains,
12// order new ones and changing specific domain properties
13type Repository repository.RestRepository
14
15// GetAll returns all domains listed in your account
16func (r *Repository) GetAll() ([]Domain, error) {
17	var response domainsResponse
18	err := r.Client.Get(rest.Request{Endpoint: "/domains"}, &response)
19
20	return response.Domains, err
21}
22
23// GetAllByTags returns a list of all Domains that match the tags provided
24func (r *Repository) GetAllByTags(tags []string) ([]Domain, error) {
25	var response domainsResponse
26	restRequest := rest.Request{Endpoint: "/domains", Parameters: url.Values{"tags": tags}}
27	err := r.Client.Get(restRequest, &response)
28
29	return response.Domains, err
30}
31
32// GetSelection returns a limited list of all domains in your account,
33// specify how many and which page/chunk of domains you want to retrieve
34func (r *Repository) GetSelection(page int, itemsPerPage int) ([]Domain, error) {
35	var response domainsResponse
36	params := url.Values{
37		"pageSize": []string{fmt.Sprintf("%d", itemsPerPage)},
38		"page":     []string{fmt.Sprintf("%d", page)},
39	}
40
41	restRequest := rest.Request{Endpoint: "/domains", Parameters: params}
42	err := r.Client.Get(restRequest, &response)
43
44	return response.Domains, err
45}
46
47// GetByDomainName returns a Domain struct for a specific domain name.
48//
49// Requires a domainName, for example: 'example.com'
50func (r *Repository) GetByDomainName(domainName string) (Domain, error) {
51	var response domainWrapper
52	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s", domainName)}
53	err := r.Client.Get(restRequest, &response)
54
55	return response.Domain, err
56}
57
58// Register allows you to registers a new domain.
59// You can set the contacts, nameservers and DNS entries immediately, but it’s not mandatory for registration.
60func (r *Repository) Register(domainRegister Register) error {
61	restRequest := rest.Request{Endpoint: "/domains", Body: &domainRegister}
62
63	return r.Client.Post(restRequest)
64}
65
66// Transfer allows you to transfer a domain to TransIP using its transfer key
67// (or ‘EPP code’) by specifying it in the authCode parameter
68func (r *Repository) Transfer(domainTransfer Transfer) error {
69	restRequest := rest.Request{Endpoint: "/domains", Body: &domainTransfer}
70
71	return r.Client.Post(restRequest)
72}
73
74// Update an existing domain.
75// To apply or release a lock, change the IsTransferLocked property.
76// To change tags, update the tags property.
77func (r *Repository) Update(domain Domain) error {
78	requestBody := domainWrapper{Domain: domain}
79	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s", domain.Name), Body: &requestBody}
80
81	return r.Client.Put(restRequest)
82}
83
84// Cancel cancels the specified domain.
85// Depending on the time you want to cancel the domain,
86// specify gotransip.CancellationTimeEnd or gotransip.CancellationTimeImmediately for the endTime attribute.
87func (r *Repository) Cancel(domainName string, endTime gotransip.CancellationTime) error {
88	var requestBody gotransip.CancellationRequest
89	requestBody.EndTime = endTime
90	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s", domainName), Body: &requestBody}
91
92	return r.Client.Delete(restRequest)
93}
94
95// GetBranding returns a Branding struct for the given domain.
96// Branding can be altered using the method below
97func (r *Repository) GetBranding(domainName string) (Branding, error) {
98	var response domainBrandingWrapper
99	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/branding", domainName)}
100	err := r.Client.Get(restRequest, &response)
101
102	return response.Branding, err
103}
104
105// UpdateBranding allows you to change the branding information on a domain
106func (r *Repository) UpdateBranding(domainName string, branding Branding) error {
107	requestBody := domainBrandingWrapper{Branding: branding}
108	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/branding", domainName), Body: &requestBody}
109
110	return r.Client.Put(restRequest)
111}
112
113// GetContacts returns a list of contacts for the given domain name
114func (r *Repository) GetContacts(domainName string) ([]WhoisContact, error) {
115	var response contactsWrapper
116	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/contacts", domainName)}
117	err := r.Client.Get(restRequest, &response)
118
119	return response.Contacts, err
120}
121
122// UpdateContacts allows you to replace the whois contacts currently on a domain
123func (r *Repository) UpdateContacts(domainName string, contacts []WhoisContact) error {
124	requestBody := contactsWrapper{Contacts: contacts}
125	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/contacts", domainName), Body: &requestBody}
126
127	return r.Client.Put(restRequest)
128}
129
130// GetDNSEntries returns a list of all DNS entries for a domain by domainName
131func (r *Repository) GetDNSEntries(domainName string) ([]DNSEntry, error) {
132	var response dnsEntriesWrapper
133	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dns", domainName)}
134	err := r.Client.Get(restRequest, &response)
135
136	return response.DNSEntries, err
137}
138
139// AddDNSEntry allows you to add a single dns entry to a domain
140func (r *Repository) AddDNSEntry(domainName string, dnsEntry DNSEntry) error {
141	requestBody := dnsEntryWrapper{DNSEntry: dnsEntry}
142	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dns", domainName), Body: &requestBody}
143
144	return r.Client.Post(restRequest)
145}
146
147// UpdateDNSEntry updates the content of a single DNS entry,
148// the dns entry is identified by the 'Name', 'Expire' and 'Type' properties of the DNSEntry struct
149func (r *Repository) UpdateDNSEntry(domainName string, dnsEntry DNSEntry) error {
150	requestBody := dnsEntryWrapper{DNSEntry: dnsEntry}
151	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dns", domainName), Body: &requestBody}
152
153	return r.Client.Patch(restRequest)
154}
155
156// ReplaceDNSEntries will wipe the entire zone replacing it with the given dns entries
157func (r *Repository) ReplaceDNSEntries(domainName string, dnsEntries []DNSEntry) error {
158	requestBody := dnsEntriesWrapper{DNSEntries: dnsEntries}
159	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dns", domainName), Body: &requestBody}
160
161	return r.Client.Put(restRequest)
162}
163
164// RemoveDNSEntry allows you to remove a single DNS entry from a domain
165func (r *Repository) RemoveDNSEntry(domainName string, dnsEntry DNSEntry) error {
166	requestBody := dnsEntryWrapper{DNSEntry: dnsEntry}
167	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dns", domainName), Body: &requestBody}
168
169	return r.Client.Delete(restRequest)
170}
171
172// GetDNSSecEntries returns a list of all DNS Sec entries for a domain by domainName
173func (r *Repository) GetDNSSecEntries(domainName string) ([]DNSSecEntry, error) {
174	var response dnsSecEntriesWrapper
175	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dnssec", domainName)}
176	err := r.Client.Get(restRequest, &response)
177
178	return response.DNSSecEntries, err
179}
180
181// ReplaceDNSSecEntries allows you to replace all DNSSEC entries with the ones that are provided
182func (r *Repository) ReplaceDNSSecEntries(domainName string, dnsSecEntries []DNSSecEntry) error {
183	requestBody := dnsSecEntriesWrapper{DNSSecEntries: dnsSecEntries}
184	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/dnssec", domainName), Body: &requestBody}
185
186	return r.Client.Put(restRequest)
187}
188
189// GetNameservers will list all nameservers currently set for a domain.
190func (r *Repository) GetNameservers(domainName string) ([]Nameserver, error) {
191	var response nameserversWrapper
192	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/nameservers", domainName)}
193	err := r.Client.Get(restRequest, &response)
194
195	return response.Nameservers, err
196}
197
198// UpdateNameservers allows you to change the nameservers for a domain
199func (r *Repository) UpdateNameservers(domainName string, nameservers []Nameserver) error {
200	requestBody := nameserversWrapper{Nameservers: nameservers}
201	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/nameservers", domainName), Body: &requestBody}
202
203	return r.Client.Put(restRequest)
204}
205
206// GetDomainAction allows you to get the current domain action running for the given domain.
207// Domain actions are kept track of by TransIP. Domain actions include, for example, changing nameservers.
208func (r *Repository) GetDomainAction(domainName string) (Action, error) {
209	var response actionWrapper
210	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/actions", domainName)}
211	err := r.Client.Get(restRequest, &response)
212
213	return response.Action, err
214}
215
216// RetryDomainAction allows you to retry a failed domain action.
217// Domain actions can fail due to wrong information, this method allows you to retry an action.
218func (r *Repository) RetryDomainAction(domainName string, authCode string, dnsEntries []DNSEntry, nameservers []Nameserver, contacts []WhoisContact) error {
219	var requestBody retryActionWrapper
220	requestBody.AuthCode = authCode
221	requestBody.DNSEntries = dnsEntries
222	requestBody.Nameservers = nameservers
223	requestBody.Contacts = contacts
224	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/actions", domainName), Body: &requestBody}
225
226	return r.Client.Patch(restRequest)
227}
228
229// CancelDomainAction allows you to cancel a domain action while it is still pending or being processed
230func (r *Repository) CancelDomainAction(domainName string) error {
231	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/actions", domainName)}
232
233	return r.Client.Delete(restRequest)
234}
235
236// GetSSLCertificates allows you to get a list of SSL certificates for a specific domain
237func (r *Repository) GetSSLCertificates(domainName string) ([]SslCertificate, error) {
238	var response certificatesWrapper
239	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/ssl", domainName)}
240	err := r.Client.Get(restRequest, &response)
241
242	return response.Certificates, err
243}
244
245// GetSSLCertificateByID allows you to get a single SSL certificate by id.
246func (r *Repository) GetSSLCertificateByID(domainName string, certificateID int64) (SslCertificate, error) {
247	var response certificateWrapper
248	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/ssl/%d", domainName, certificateID)}
249	err := r.Client.Get(restRequest, &response)
250
251	return response.Certificate, err
252}
253
254// GetWHOIS will return the WHOIS information for a domain name as a string
255func (r *Repository) GetWHOIS(domainName string) (string, error) {
256	var response whoisWrapper
257	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domains/%s/whois", domainName)}
258	err := r.Client.Get(restRequest, &response)
259
260	return response.Whois, err
261}
262
263// OrderWhitelabel allows you to order a whitelabel account.
264// Note that you do not need to order a whitelabel account for every registered domain name.
265func (r *Repository) OrderWhitelabel() error {
266	restRequest := rest.Request{Endpoint: "/whitelabel"}
267
268	return r.Client.Post(restRequest)
269}
270
271// GetAvailability method allows you to check the availability for a domain name
272func (r *Repository) GetAvailability(domainName string) (Availability, error) {
273	var response availabilityWrapper
274	restRequest := rest.Request{Endpoint: fmt.Sprintf("/domain-availability/%s", domainName)}
275	err := r.Client.Get(restRequest, &response)
276
277	return response.Availability, err
278}
279
280// GetAvailabilityForMultipleDomains method allows you to check the availability for a list of domain names
281func (r *Repository) GetAvailabilityForMultipleDomains(domainNames []string) ([]Availability, error) {
282	var response availabilityListWrapper
283	var requestBody multipleAvailabilityRequest
284	requestBody.DomainNames = domainNames
285
286	restRequest := rest.Request{Endpoint: "/domain-availability", Body: requestBody}
287	err := r.Client.Get(restRequest, &response)
288
289	return response.AvailabilityList, err
290}
291
292// GetTLDs will return a list of all available TLDs currently offered by TransIP
293func (r *Repository) GetTLDs() ([]Tld, error) {
294	var response tldsWrapper
295	restRequest := rest.Request{Endpoint: "/tlds"}
296	err := r.Client.Get(restRequest, &response)
297
298	return response.Tlds, err
299}
300
301// GetTLDByTLD returns information about a specific TLD.
302// General details such as price, renewal price and minimum registration length are outlined.
303func (r *Repository) GetTLDByTLD(tld string) (Tld, error) {
304	var response tldWrapper
305	restRequest := rest.Request{Endpoint: fmt.Sprintf("/tlds/%s", tld)}
306	err := r.Client.Get(restRequest, &response)
307
308	return response.Tld, err
309}
310