1package papi
2
3import (
4	"encoding/json"
5	"fmt"
6
7	"github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1"
8	edge "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
9	"github.com/patrickmn/go-cache"
10)
11
12// Groups represents a collection of PAPI groups
13type Groups struct {
14	client.Resource
15	AccountID   string `json:"accountId"`
16	AccountName string `json:"accountName"`
17	Groups      struct {
18		Items []*Group `json:"items"`
19	} `json:"groups"`
20}
21
22// NewGroups creates a new Groups
23func NewGroups() *Groups {
24	groups := &Groups{}
25	return groups
26}
27
28// PostUnmarshalJSON is called after JSON unmarshaling into EdgeHostnames
29//
30// See: jsonhooks-v1/jsonhooks.Unmarshal()
31func (groups *Groups) PostUnmarshalJSON() error {
32	groups.Init()
33	for key, group := range groups.Groups.Items {
34		groups.Groups.Items[key].parent = groups
35		if err := group.PostUnmarshalJSON(); err != nil {
36			return err
37		}
38	}
39
40	groups.Complete <- true
41
42	return nil
43}
44
45// GetGroups populates Groups with group data
46//
47// API Docs: https://developer.akamai.com/api/luna/papi/resources.html#listgroups
48// Endpoint: GET /papi/v1/groups/
49func (groups *Groups) GetGroups(correlationid string) error {
50	cachegroups, found := Profilecache.Get("groups")
51	if found {
52		json.Unmarshal(cachegroups.([]byte), groups)
53		return nil
54	} else {
55		req, err := client.NewRequest(
56			Config,
57			"GET",
58			"/papi/v1/groups",
59			nil,
60		)
61		if err != nil {
62			return err
63		}
64
65		edge.PrintHttpRequestCorrelation(req, true, correlationid)
66
67		res, err := client.Do(Config, req)
68		if err != nil {
69			return err
70		}
71
72		edge.PrintHttpResponseCorrelation(res, true, correlationid)
73
74		if client.IsError(res) {
75			return client.NewAPIError(res)
76		}
77
78		if err = client.BodyJSON(res, groups); err != nil {
79			return err
80		}
81		byt, _ := json.Marshal(groups)
82		Profilecache.Set("groups", byt, cache.DefaultExpiration)
83		return nil
84	}
85}
86
87// AddGroup adds a group to a Groups collection
88func (groups *Groups) AddGroup(newGroup *Group) {
89	if newGroup.GroupID != "" {
90		for key, group := range groups.Groups.Items {
91			if group.GroupID == newGroup.GroupID {
92				groups.Groups.Items[key] = newGroup
93				return
94			}
95		}
96	}
97
98	newGroup.parent = groups
99
100	groups.Groups.Items = append(groups.Groups.Items, newGroup)
101}
102
103// FindGroup finds a specific group by ID
104func (groups *Groups) FindGroup(id string) (*Group, error) {
105	var group *Group
106	var groupFound bool
107
108	if id == "" {
109		goto err
110	}
111
112	for _, group = range groups.Groups.Items {
113		if group.GroupID == id {
114			groupFound = true
115			break
116		}
117	}
118
119err:
120	if !groupFound {
121		return nil, fmt.Errorf("Unable to find group: \"%s\"", id)
122	}
123
124	return group, nil
125}
126
127// FindGroupId finds a specific group by name
128// Deprecated: When there are multiple groups with same name,
129// the first one is returned. Please use FindGroupsByName instead.
130func (groups *Groups) FindGroupId(name string) (*Group, error) {
131	var group *Group
132	var groupFound bool
133
134	if name == "" {
135		goto err
136	}
137
138	for _, group = range groups.Groups.Items {
139		if group.GroupName == name {
140			groupFound = true
141			break
142		}
143	}
144
145err:
146	if !groupFound {
147		return nil, fmt.Errorf("Unable to find group: \"%s\"", name)
148	}
149
150	return group, nil
151}
152
153// FindGroupsByName finds groups by name
154func (groups *Groups) FindGroupsByName(name string) ([]*Group, error) {
155	var group *Group
156	var foundGroups []*Group
157	var groupFound bool
158
159	if name == "" {
160		goto err
161	}
162
163	for _, group = range groups.Groups.Items {
164		if group.GroupName == name {
165			foundGroups = append(foundGroups, group)
166			groupFound = true
167		}
168	}
169
170err:
171	if !groupFound {
172		return nil, fmt.Errorf("Unable to find group: \"%s\"", name)
173	}
174
175	return foundGroups, nil
176}
177
178// Group represents a group resource
179type Group struct {
180	client.Resource
181	parent        *Groups
182	GroupName     string   `json:"groupName"`
183	GroupID       string   `json:"groupId"`
184	ParentGroupID string   `json:"parentGroupId,omitempty"`
185	ContractIDs   []string `json:"contractIds"`
186}
187
188// NewGroup creates a new Group
189func NewGroup(parent *Groups) *Group {
190	group := &Group{
191		parent: parent,
192	}
193	group.Init()
194	return group
195}
196
197// GetGroup populates a Group
198func (group *Group) GetGroup() {
199	groups, err := GetGroups()
200	if err != nil {
201		return
202	}
203
204	for _, g := range groups.Groups.Items {
205		if g.GroupID == group.GroupID {
206			group.parent = groups
207			group.ContractIDs = g.ContractIDs
208			group.GroupName = g.GroupName
209			group.ParentGroupID = g.ParentGroupID
210			group.Complete <- true
211			return
212		}
213	}
214
215	group.Complete <- false
216}
217
218// GetProperties retrieves all properties associated with a given group and contract
219func (group *Group) GetProperties(contract *Contract) (*Properties, error) {
220	return GetProperties(contract, group)
221}
222
223// GetCpCodes retrieves all CP codes associated with a given group and contract
224func (group *Group) GetCpCodes(contract *Contract) (*CpCodes, error) {
225	return GetCpCodes(contract, group)
226}
227
228// GetEdgeHostnames retrieves all Edge hostnames associated with a given group/contract
229func (group *Group) GetEdgeHostnames(contract *Contract, options string, correlationid string) (*EdgeHostnames, error) {
230	return GetEdgeHostnames(contract, group, options)
231}
232
233// NewProperty creates a property associated with a given group/contract
234func (group *Group) NewProperty(contract *Contract) (*Property, error) {
235	property := NewProperty(NewProperties())
236	property.Contract = contract
237	property.Group = group
238	return property, nil
239}
240