1package lib
2
3import (
4	"fmt"
5	"sort"
6	"strconv"
7	"strings"
8)
9
10// Plan on Vultr
11type Plan struct {
12	ID        int    `json:"VPSPLANID,string"`
13	Name      string `json:"name"`
14	VCpus     int    `json:"vcpu_count,string"`
15	RAM       string `json:"ram"`
16	Disk      string `json:"disk"`
17	Bandwidth string `json:"bandwidth"`
18	Price     string `json:"price_per_month"`
19	PlanType  string `json:"plan_type"`
20	Windows   bool   `json:"windows"`
21	Regions   []int  `json:"available_locations"`
22}
23
24type plans []Plan
25
26func (p plans) Len() int      { return len(p) }
27func (p plans) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
28func (p plans) Less(i, j int) bool {
29	pa, _ := strconv.ParseFloat(strings.TrimSpace(p[i].Price), 64)
30	pb, _ := strconv.ParseFloat(strings.TrimSpace(p[j].Price), 64)
31	ra, _ := strconv.ParseInt(strings.TrimSpace(p[i].RAM), 10, 64)
32	rb, _ := strconv.ParseInt(strings.TrimSpace(p[j].RAM), 10, 64)
33	da, _ := strconv.ParseInt(strings.TrimSpace(p[i].Disk), 10, 64)
34	db, _ := strconv.ParseInt(strings.TrimSpace(p[j].Disk), 10, 64)
35
36	// sort order: price, vcpu, ram, disk
37	if pa < pb {
38		return true
39	} else if pa > pb {
40		return false
41	}
42
43	if p[i].VCpus < p[j].VCpus {
44		return true
45	} else if p[i].VCpus > p[j].VCpus {
46		return false
47	}
48
49	if ra < rb {
50		return true
51	} else if ra > rb {
52		return false
53	}
54
55	return da < db
56}
57
58// GetPlans returns a list of all available plans on Vultr account
59func (c *Client) GetPlans() ([]Plan, error) {
60	var planMap map[string]Plan
61	if err := c.get(`plans/list`, &planMap); err != nil {
62		return nil, err
63	}
64
65	var p plans
66	for _, plan := range planMap {
67		p = append(p, plan)
68	}
69
70	sort.Sort(plans(p))
71	return p, nil
72}
73
74// GetAvailablePlansForRegion returns available plans for specified region
75func (c *Client) GetAvailablePlansForRegion(id int) (planIDs []int, err error) {
76	if err := c.get(fmt.Sprintf(`regions/availability?DCID=%v`, id), &planIDs); err != nil {
77		return nil, err
78	}
79	return
80}
81