1package cfclient
2
3import (
4	"bytes"
5	"encoding/json"
6	"fmt"
7	"io/ioutil"
8	"net/url"
9
10	"github.com/pkg/errors"
11)
12
13type ServicePlansResponse struct {
14	Count     int                   `json:"total_results"`
15	Pages     int                   `json:"total_pages"`
16	NextUrl   string                `json:"next_url"`
17	Resources []ServicePlanResource `json:"resources"`
18}
19
20type ServicePlanResource struct {
21	Meta   Meta        `json:"metadata"`
22	Entity ServicePlan `json:"entity"`
23}
24
25type ServicePlan struct {
26	Name                string      `json:"name"`
27	Guid                string      `json:"guid"`
28	CreatedAt           string      `json:"created_at"`
29	UpdatedAt           string      `json:"updated_at"`
30	Free                bool        `json:"free"`
31	Description         string      `json:"description"`
32	ServiceGuid         string      `json:"service_guid"`
33	Extra               interface{} `json:"extra"`
34	UniqueId            string      `json:"unique_id"`
35	Public              bool        `json:"public"`
36	Active              bool        `json:"active"`
37	Bindable            bool        `json:"bindable"`
38	ServiceUrl          string      `json:"service_url"`
39	ServiceInstancesUrl string      `json:"service_instances_url"`
40	c                   *Client
41}
42
43func (c *Client) ListServicePlansByQuery(query url.Values) ([]ServicePlan, error) {
44	var servicePlans []ServicePlan
45	requestUrl := "/v2/service_plans?" + query.Encode()
46	for {
47		var servicePlansResp ServicePlansResponse
48		r := c.NewRequest("GET", requestUrl)
49		resp, err := c.DoRequest(r)
50		if err != nil {
51			return nil, errors.Wrap(err, "Error requesting service plans")
52		}
53		resBody, err := ioutil.ReadAll(resp.Body)
54		if err != nil {
55			return nil, errors.Wrap(err, "Error reading service plans request:")
56		}
57		err = json.Unmarshal(resBody, &servicePlansResp)
58		if err != nil {
59			return nil, errors.Wrap(err, "Error unmarshaling service plans")
60		}
61		for _, servicePlan := range servicePlansResp.Resources {
62			servicePlan.Entity.Guid = servicePlan.Meta.Guid
63			servicePlan.Entity.CreatedAt = servicePlan.Meta.CreatedAt
64			servicePlan.Entity.UpdatedAt = servicePlan.Meta.UpdatedAt
65			servicePlan.Entity.c = c
66			servicePlans = append(servicePlans, servicePlan.Entity)
67		}
68		requestUrl = servicePlansResp.NextUrl
69		if requestUrl == "" {
70			break
71		}
72	}
73	return servicePlans, nil
74}
75
76func (c *Client) ListServicePlans() ([]ServicePlan, error) {
77	return c.ListServicePlansByQuery(nil)
78}
79
80func (c *Client) GetServicePlanByGUID(guid string) (*ServicePlan, error) {
81	var (
82		plan         *ServicePlan
83		planResponse ServicePlanResource
84	)
85
86	r := c.NewRequest("GET", "/v2/service_plans/"+guid)
87	resp, err := c.DoRequest(r)
88	if err != nil {
89		return nil, err
90	}
91
92	body, err := ioutil.ReadAll(resp.Body)
93	defer resp.Body.Close()
94	if err != nil {
95		return nil, err
96	}
97
98	err = json.Unmarshal(body, &planResponse)
99	if err != nil {
100		return nil, err
101	}
102
103	planResponse.Entity.Guid = planResponse.Meta.Guid
104	planResponse.Entity.CreatedAt = planResponse.Meta.CreatedAt
105	planResponse.Entity.UpdatedAt = planResponse.Meta.UpdatedAt
106	plan = &planResponse.Entity
107
108	return plan, nil
109}
110
111func (c *Client) MakeServicePlanPublic(servicePlanGUID string) error {
112	return c.setPlanGlobalVisibility(servicePlanGUID, true)
113}
114
115func (c *Client) MakeServicePlanPrivate(servicePlanGUID string) error {
116	return c.setPlanGlobalVisibility(servicePlanGUID, false)
117}
118
119func (c *Client) setPlanGlobalVisibility(servicePlanGUID string, public bool) error {
120	bodyString := fmt.Sprintf(`{"public": %t}`, public)
121	req := c.NewRequestWithBody("PUT", fmt.Sprintf("/v2/service_plans/%s", servicePlanGUID), bytes.NewBufferString(bodyString))
122
123	resp, err := c.DoRequest(req)
124	if err != nil {
125		return err
126	}
127	defer resp.Body.Close()
128	return nil
129}
130