1// Copyright 2017 The go-github AUTHORS. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6package github
7
8import (
9	"context"
10	"fmt"
11)
12
13// MarketplaceService handles communication with the marketplace related
14// methods of the GitHub API.
15//
16// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
17type MarketplaceService struct {
18	client *Client
19	// Stubbed controls whether endpoints that return stubbed data are used
20	// instead of production endpoints. Stubbed data is fake data that's useful
21	// for testing your GitHub Apps. Stubbed data is hard-coded and will not
22	// change based on actual subscriptions.
23	//
24	// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
25	Stubbed bool
26}
27
28// MarketplacePlan represents a GitHub Apps Marketplace Listing Plan.
29type MarketplacePlan struct {
30	URL                 *string   `json:"url,omitempty"`
31	AccountsURL         *string   `json:"accounts_url,omitempty"`
32	ID                  *int64    `json:"id,omitempty"`
33	Name                *string   `json:"name,omitempty"`
34	Description         *string   `json:"description,omitempty"`
35	MonthlyPriceInCents *int      `json:"monthly_price_in_cents,omitempty"`
36	YearlyPriceInCents  *int      `json:"yearly_price_in_cents,omitempty"`
37	PriceModel          *string   `json:"price_model,omitempty"`
38	UnitName            *string   `json:"unit_name,omitempty"`
39	Bullets             *[]string `json:"bullets,omitempty"`
40}
41
42// MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
43type MarketplacePurchase struct {
44	BillingCycle    *string                 `json:"billing_cycle,omitempty"`
45	NextBillingDate *string                 `json:"next_billing_date,omitempty"`
46	UnitCount       *int                    `json:"unit_count,omitempty"`
47	Plan            *MarketplacePlan        `json:"plan,omitempty"`
48	Account         *MarketplacePlanAccount `json:"account,omitempty"`
49}
50
51// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan.
52type MarketplacePlanAccount struct {
53	URL                      *string              `json:"url,omitempty"`
54	Type                     *string              `json:"type,omitempty"`
55	ID                       *int64               `json:"id,omitempty"`
56	Login                    *string              `json:"login,omitempty"`
57	Email                    *string              `json:"email,omitempty"`
58	OrganizationBillingEmail *string              `json:"organization_billing_email,omitempty"`
59	MarketplacePurchase      *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
60}
61
62// ListPlans lists all plans for your Marketplace listing.
63//
64// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
65func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([]*MarketplacePlan, *Response, error) {
66	uri := s.marketplaceURI("plans")
67	u, err := addOptions(uri, opt)
68	if err != nil {
69		return nil, nil, err
70	}
71
72	req, err := s.client.NewRequest("GET", u, nil)
73	if err != nil {
74		return nil, nil, err
75	}
76
77	var plans []*MarketplacePlan
78	resp, err := s.client.Do(ctx, req, &plans)
79	if err != nil {
80		return nil, resp, err
81	}
82
83	return plans, resp, nil
84}
85
86// ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan.
87//
88// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
89func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
90	uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID))
91	u, err := addOptions(uri, opt)
92	if err != nil {
93		return nil, nil, err
94	}
95
96	req, err := s.client.NewRequest("GET", u, nil)
97	if err != nil {
98		return nil, nil, err
99	}
100
101	var accounts []*MarketplacePlanAccount
102	resp, err := s.client.Do(ctx, req, &accounts)
103	if err != nil {
104		return nil, resp, err
105	}
106
107	return accounts, resp, nil
108}
109
110// ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account.
111//
112// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
113func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
114	uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID))
115	u, err := addOptions(uri, opt)
116	if err != nil {
117		return nil, nil, err
118	}
119
120	req, err := s.client.NewRequest("GET", u, nil)
121	if err != nil {
122		return nil, nil, err
123	}
124
125	var accounts []*MarketplacePlanAccount
126	resp, err := s.client.Do(ctx, req, &accounts)
127	if err != nil {
128		return nil, resp, err
129	}
130
131	return accounts, resp, nil
132}
133
134// ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user.
135//
136// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases
137func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opt *ListOptions) ([]*MarketplacePurchase, *Response, error) {
138	uri := "user/marketplace_purchases"
139	if s.Stubbed {
140		uri = "user/marketplace_purchases/stubbed"
141	}
142
143	u, err := addOptions(uri, opt)
144	if err != nil {
145		return nil, nil, err
146	}
147
148	req, err := s.client.NewRequest("GET", u, nil)
149	if err != nil {
150		return nil, nil, err
151	}
152
153	var purchases []*MarketplacePurchase
154	resp, err := s.client.Do(ctx, req, &purchases)
155	if err != nil {
156		return nil, resp, err
157	}
158
159	return purchases, resp, nil
160}
161
162func (s *MarketplaceService) marketplaceURI(endpoint string) string {
163	url := "marketplace_listing"
164	if s.Stubbed {
165		url = "marketplace_listing/stubbed"
166	}
167	return url + "/" + endpoint
168}
169