package servers

import (
	"fmt"
	"github.com/rackspace/gophercloud/openstack/identity"
)

// Client abstracts the connection information needed to make API requests for OpenStack compute endpoints.
type Client struct {
	endpoint	string
	authority	identity.AuthResults
	options		identity.AuthOptions
	token		*identity.Token
}

// NewClient creates a new Client structure to use when issuing requests to the server.
func NewClient(e string, a identity.AuthResults, o identity.AuthOptions) *Client {
	return &Client{
		endpoint:	e,
		authority:	a,
		options:	o,
	}
}

func (c *Client) getListUrl() string {
	return fmt.Sprintf("%s/servers/detail", c.endpoint)
}

func (c *Client) getCreateUrl() string {
	return fmt.Sprintf("%s/servers", c.endpoint)
}

func (c *Client) getDeleteUrl(id string) string {
	return fmt.Sprintf("%s/servers/%s", c.endpoint, id)
}

func (c *Client) getDetailUrl(id string) string {
	return c.getDeleteUrl(id)
}

func (c *Client) getUpdateUrl(id string) string {
	return c.getDeleteUrl(id)
}

func (c *Client) getListHeaders() (map[string]string, error) {
	t, err := c.getAuthToken()
	if err != nil {
		return map[string]string{}, err
	}

	return map[string]string{
		"X-Auth-Token": t,
	}, nil
}

func (c *Client) getCreateHeaders() (map[string]string, error) {
	return c.getListHeaders()
}

func (c *Client) getDeleteHeaders() (map[string]string, error) {
	return c.getListHeaders()
}

func (c *Client) getDetailHeaders() (map[string]string, error) {
	return c.getListHeaders()
}

func (c *Client) getUpdateHeaders() (map[string]string, error) {
	return c.getListHeaders()
}

func (c *Client) getAuthToken() (string, error) {
	var err error

	if c.token == nil {
		c.token, err = identity.GetToken(c.authority)
		if err != nil {
			return "", err
		}
	}

	return c.token.Id, err
}

