// TODO(sfalvo): Remove Rackspace-specific Server structure fields and refactor them into a provider-specific access method.
// Be sure to update godocs accordingly.

package gophercloud

import (
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/racker/perigee"
	"strings"
)

// genericServersProvider structures provide the implementation for generic OpenStack-compatible
// CloudServersProvider interfaces.
type genericServersProvider struct {
	// endpoint refers to the provider's API endpoint base URL.  This will be used to construct
	// and issue queries.
	endpoint string

	// Test context (if any) in which to issue requests.
	context *Context

	// access associates this API provider with a set of credentials,
	// which may be automatically renewed if they near expiration.
	access AccessProvider
}

// See the CloudServersProvider interface for details.
func (gcp *genericServersProvider) ListServersLinksOnly() ([]Server, error) {
	var ss []Server

	err := gcp.context.WithReauth(gcp.access, func() error {
		url := gcp.endpoint + "/servers"
		return perigee.Get(url, perigee.Options{
			CustomClient: gcp.context.httpClient,
			Results:      &struct{ Servers *[]Server }{&ss},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gcp.access.AuthToken(),
			},
		})
	})
	return ss, err
}

// See the CloudServersProvider interface for details.
func (gcp *genericServersProvider) ListServers() ([]Server, error) {
	var ss []Server

	err := gcp.context.WithReauth(gcp.access, func() error {
		url := gcp.endpoint + "/servers/detail"
		return perigee.Get(url, perigee.Options{
			CustomClient: gcp.context.httpClient,
			Results:      &struct{ Servers *[]Server }{&ss},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gcp.access.AuthToken(),
			},
		})
	})

	// Compatibility with v0.0.x -- we "map" our public and private
	// addresses into a legacy structure field for the benefit of
	// earlier software.

	if err != nil {
		return ss, err
	}

	for _, s := range ss {
		err = mapstructure.Decode(s.RawAddresses, &s.Addresses)
		if err != nil {
			return ss, err
		}
	}

	return ss, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ServerById(id string) (*Server, error) {
	var s *Server

	err := gsp.context.WithReauth(gsp.access, func() error {
		url := gsp.endpoint + "/servers/" + id
		return perigee.Get(url, perigee.Options{
			Results: &struct{ Server **Server }{&s},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})

	// Compatibility with v0.0.x -- we "map" our public and private
	// addresses into a legacy structure field for the benefit of
	// earlier software.

	if err != nil {
		return s, err
	}

	err = mapstructure.Decode(s.RawAddresses, &s.Addresses)

	return s, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) CreateServer(ns NewServer) (*NewServer, error) {
	var s *NewServer

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := gsp.endpoint + "/servers"
		return perigee.Post(ep, perigee.Options{
			ReqBody: &struct {
				Server *NewServer `json:"server"`
			}{&ns},
			Results: &struct{ Server **NewServer }{&s},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{202},
		})
	})

	return s, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) DeleteServerById(id string) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := gsp.endpoint + "/servers/" + id
		return perigee.Delete(url, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{204},
		})
	})
	return err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) SetAdminPassword(id, pw string) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				ChangePassword struct {
					AdminPass string `json:"adminPass"`
				} `json:"changePassword"`
			}{
				struct {
					AdminPass string `json:"adminPass"`
				}{pw},
			},
			OkCodes: []int{202},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})
	return err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ResizeServer(id, newName, newFlavor, newDiskConfig string) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		rr := ResizeRequest{
			Name:       newName,
			FlavorRef:  newFlavor,
			DiskConfig: newDiskConfig,
		}
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				Resize ResizeRequest `json:"resize"`
			}{rr},
			OkCodes: []int{202},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})
	return err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) RevertResize(id string) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				RevertResize *int `json:"revertResize"`
			}{nil},
			OkCodes: []int{202},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})
	return err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ConfirmResize(id string) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				ConfirmResize *int `json:"confirmResize"`
			}{nil},
			OkCodes: []int{204},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})
	return err
}

// See the CloudServersProvider interface for details
func (gsp *genericServersProvider) RebootServer(id string, hard bool) error {
	return gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		types := map[bool]string{false: "SOFT", true: "HARD"}
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				Reboot struct {
					Type string `json:"type"`
				} `json:"reboot"`
			}{
				struct {
					Type string `json:"type"`
				}{types[hard]},
			},
			OkCodes: []int{202},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
		})
	})
}

// See the CloudServersProvider interface for details
func (gsp *genericServersProvider) RescueServer(id string) (string, error) {
	var pw *string

	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				Rescue string `json:"rescue"`
			}{"none"},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				AdminPass **string `json:"adminPass"`
			}{&pw},
		})
	})
	return *pw, err
}

// See the CloudServersProvider interface for details
func (gsp *genericServersProvider) UnrescueServer(id string) error {
	return gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(url, perigee.Options{
			ReqBody: &struct {
				Unrescue *int `json:"unrescue"`
			}{nil},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{202},
		})
	})
}

// See the CloudServersProvider interface for details
func (gsp *genericServersProvider) UpdateServer(id string, changes NewServerSettings) (*Server, error) {
	var svr *Server
	err := gsp.context.WithReauth(gsp.access, func() error {
		url := fmt.Sprintf("%s/servers/%s", gsp.endpoint, id)
		return perigee.Put(url, perigee.Options{
			ReqBody: &struct {
				Server NewServerSettings `json:"server"`
			}{changes},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				Server **Server `json:"server"`
			}{&svr},
		})
	})
	return svr, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) RebuildServer(id string, ns NewServer) (*Server, error) {
	var s *Server

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Post(ep, perigee.Options{
			ReqBody: &struct {
				Rebuild *NewServer `json:"rebuild"`
			}{&ns},
			Results: &struct{ Server **Server }{&s},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{202},
		})
	})

	return s, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ListAddresses(id string) (AddressSet, error) {
	var pas *AddressSet
	var statusCode int

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/servers/%s/ips", gsp.endpoint, id)
		return perigee.Get(ep, perigee.Options{
			Results: &struct{ Addresses **AddressSet }{&pas},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes:    []int{200, 203},
			StatusCode: &statusCode,
		})
	})

	if err != nil {
		if statusCode == 203 {
			err = WarnUnauthoritative
		}
	}

	return *pas, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ListAddressesByNetwork(id, networkLabel string) (NetworkAddress, error) {
	pas := make(NetworkAddress)
	var statusCode int

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/servers/%s/ips/%s", gsp.endpoint, id, networkLabel)
		return perigee.Get(ep, perigee.Options{
			Results: &pas,
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes:    []int{200, 203},
			StatusCode: &statusCode,
		})
	})

	if err != nil {
		if statusCode == 203 {
			err = WarnUnauthoritative
		}
	}

	return pas, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) CreateImage(id string, ci CreateImage) (string, error) {
	response, err := gsp.context.ResponseWithReauth(gsp.access, func() (*perigee.Response, error) {
		ep := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
		return perigee.Request("POST", ep, perigee.Options{
			ReqBody: &struct {
				CreateImage *CreateImage `json:"createImage"`
			}{&ci},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{200, 202},
		})
	})

	if err != nil {
		return "", err
	}
	location, err := response.HttpResponse.Location()
	if err != nil {
		return "", err
	}

	// Return the last element of the location which is the image id
	locationArr := strings.Split(location.Path, "/")
	return locationArr[len(locationArr)-1], err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ListSecurityGroups() ([]SecurityGroup, error) {
	var sgs []SecurityGroup

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
		return perigee.Get(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				SecurityGroups *[]SecurityGroup `json:"security_groups"`
			}{&sgs},
		})
	})
	return sgs, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error) {
	var actual *SecurityGroup

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
		return perigee.Post(ep, perigee.Options{
			ReqBody: struct {
				AddSecurityGroup SecurityGroup `json:"security_group"`
			}{desired},
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				SecurityGroup **SecurityGroup `json:"security_group"`
			}{&actual},
		})
	})
	return actual, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error) {
	var sgs []SecurityGroup

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/servers/%s/os-security-groups", gsp.endpoint, id)
		return perigee.Get(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				SecurityGroups *[]SecurityGroup `json:"security_groups"`
			}{&sgs},
		})
	})
	return sgs, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) SecurityGroupById(id int) (*SecurityGroup, error) {
	var actual *SecurityGroup

	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
		return perigee.Get(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct {
				SecurityGroup **SecurityGroup `json:"security_group"`
			}{&actual},
		})
	})
	return actual, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) DeleteSecurityGroupById(id int) error {
	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
		return perigee.Delete(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			OkCodes: []int{202},
		})
	})
	return err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) ListDefaultSGRules() ([]SGRule, error) {
	var sgrs []SGRule
	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-group-rules", gsp.endpoint)
		return perigee.Get(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct{Security_group_default_rules *[]SGRule}{&sgrs},
		})
	})
	return sgrs, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) CreateDefaultSGRule(r SGRule) error {
	var sgr *SGRule
	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-group-rules", gsp.endpoint)
		return perigee.Post(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct{Security_group_default_rule **SGRule}{&sgr},
			ReqBody: struct{Security_group_default_rule SGRule `json:"security_group_default_rule"`}{r},
		})
	})
	return sgr, err
}

// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) GetSGRule(id string) (*SGRule, error) {
	var sgr *SGRule
	err := gsp.context.WithReauth(gsp.access, func() error {
		ep := fmt.Sprintf("%s/os-security-group-rules/%s", gsp.endpoint, id)
		return perigee.Get(ep, perigee.Options{
			MoreHeaders: map[string]string{
				"X-Auth-Token": gsp.access.AuthToken(),
			},
			Results: &struct{Security_group_default_rule **SGRule}{&sgr},
		})
	})
	return sgr, err
}

// SecurityGroup provides a description of a security group, including all its rules.
type SecurityGroup struct {
	Description string   `json:"description,omitempty"`
	Id          int      `json:"id,omitempty"`
	Name        string   `json:"name,omitempty"`
	Rules       []SGRule `json:"rules,omitempty"`
	TenantId    string   `json:"tenant_id,omitempty"`
}

// SGRule encapsulates a single rule which applies to a security group.
// This definition is just a guess, based on the documentation found in another extension here: http://docs.openstack.org/api/openstack-compute/2/content/GET_os-security-group-default-rules-v2_listSecGroupDefaultRules_v2__tenant_id__os-security-group-rules_ext-os-security-group-default-rules.html
type SGRule struct {
	FromPort   int                    `json:"from_port,omitempty"`
	Id         int                    `json:"id,omitempty"`
	IpProtocol string                 `json:"ip_protocol,omitempty"`
	IpRange    map[string]interface{} `json:"ip_range,omitempty"`
	ToPort     int                    `json:"to_port,omitempty"`
}

// RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
type RaxBandwidth struct {
	AuditPeriodEnd    string `json:"audit_period_end"`
	AuditPeriodStart  string `json:"audit_period_start"`
	BandwidthInbound  int64  `json:"bandwidth_inbound"`
	BandwidthOutbound int64  `json:"bandwidth_outbound"`
	Interface         string `json:"interface"`
}

// A VersionedAddress denotes either an IPv4 or IPv6 (depending on version indicated)
// address.
type VersionedAddress struct {
	Addr    string `json:"addr"`
	Version int    `json:"version"`
}

// An AddressSet provides a set of public and private IP addresses for a resource.
// Each address has a version to identify if IPv4 or IPv6.
type AddressSet struct {
	Public  []VersionedAddress `json:"public"`
	Private []VersionedAddress `json:"private"`
}

type NetworkAddress map[string][]VersionedAddress

// Server records represent (virtual) hardware instances (not configurations) accessible by the user.
//
// The AccessIPv4 / AccessIPv6 fields provides IP addresses for the server in the IPv4 or IPv6 format, respectively.
//
// Addresses provides addresses for any attached isolated networks.
// The version field indicates whether the IP address is version 4 or 6.
// Note: only public and private pools appear here.
// To get the complete set, use the AllAddressPools() method instead.
//
// Created tells when the server entity was created.
//
// The Flavor field includes the flavor ID and flavor links.
//
// The compute provisioning algorithm has an anti-affinity property that
// attempts to spread customer VMs across hosts.
// Under certain situations,
// VMs from the same customer might be placed on the same host.
// The HostId field represents the host your server runs on and
// can be used to determine this scenario if it is relevant to your application.
// Note that HostId is unique only per account; it is not globally unique.
//
// Id provides the server's unique identifier.
// This field must be treated opaquely.
//
// Image indicates which image is installed on the server.
//
// Links provides one or more means of accessing the server.
//
// Metadata provides a small key-value store for application-specific information.
//
// Name provides a human-readable name for the server.
//
// Progress indicates how far along it is towards being provisioned.
// 100 represents complete, while 0 represents just beginning.
//
// Status provides an indication of what the server's doing at the moment.
// A server will be in ACTIVE state if it's ready for use.
//
// OsDcfDiskConfig indicates the server's boot volume configuration.
// Valid values are:
//     AUTO
//     ----
//     The server is built with a single partition the size of the target flavor disk.
//     The file system is automatically adjusted to fit the entire partition.
//     This keeps things simple and automated.
//     AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
//     This is the default setting for applicable Rackspace base images.
//
//     MANUAL
//     ------
//     The server is built using whatever partition scheme and file system is in the source image.
//     If the target flavor disk is larger,
//     the remaining disk space is left unpartitioned.
//     This enables images to have non-EXT3 file systems, multiple partitions, and so on,
//     and enables you to manage the disk configuration.
//
// RaxBandwidth provides measures of the server's inbound and outbound bandwidth per interface.
//
// OsExtStsPowerState provides an indication of the server's power.
// This field appears to be a set of flag bits:
//
//           ... 4  3   2   1   0
//         +--//--+---+---+---+---+
//         | .... | 0 | S | 0 | I |
//         +--//--+---+---+---+---+
//                      |       |
//                      |       +---  0=Instance is down.
//                      |             1=Instance is up.
//                      |
//                      +-----------  0=Server is switched ON.
//                                    1=Server is switched OFF.
//                                    (note reverse logic.)
//
// Unused bits should be ignored when read, and written as 0 for future compatibility.
//
// OsExtStsTaskState and OsExtStsVmState work together
// to provide visibility in the provisioning process for the instance.
// Consult Rackspace documentation at
// http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#ext_status
// for more details.  It's too lengthy to include here.
type Server struct {
	AccessIPv4         string `json:"accessIPv4"`
	AccessIPv6         string `json:"accessIPv6"`
	Addresses          AddressSet
	Created            string            `json:"created"`
	Flavor             FlavorLink        `json:"flavor"`
	HostId             string            `json:"hostId"`
	Id                 string            `json:"id"`
	Image              ImageLink         `json:"image"`
	Links              []Link            `json:"links"`
	Metadata           map[string]string `json:"metadata"`
	Name               string            `json:"name"`
	Progress           int               `json:"progress"`
	Status             string            `json:"status"`
	TenantId           string            `json:"tenant_id"`
	Updated            string            `json:"updated"`
	UserId             string            `json:"user_id"`
	OsDcfDiskConfig    string            `json:"OS-DCF:diskConfig"`
	RaxBandwidth       []RaxBandwidth    `json:"rax-bandwidth:bandwidth"`
	OsExtStsPowerState int               `json:"OS-EXT-STS:power_state"`
	OsExtStsTaskState  string            `json:"OS-EXT-STS:task_state"`
	OsExtStsVmState    string            `json:"OS-EXT-STS:vm_state"`

	RawAddresses map[string]interface{} `json:"addresses"`
}

// AllAddressPools returns a complete set of address pools available on the server.
// The name of each pool supported keys the map.
// The value of the map contains the addresses provided in the corresponding pool.
func (s *Server) AllAddressPools() (map[string][]VersionedAddress, error) {
	pools := make(map[string][]VersionedAddress, 0)
	for pool, subtree := range s.RawAddresses {
		addresses := make([]VersionedAddress, 0)
		err := mapstructure.Decode(subtree, &addresses)
		if err != nil {
			return nil, err
		}
		pools[pool] = addresses
	}
	return pools, nil
}

// NewServerSettings structures record those fields of the Server structure to change
// when updating a server (see UpdateServer method).
type NewServerSettings struct {
	Name       string `json:"name,omitempty"`
	AccessIPv4 string `json:"accessIPv4,omitempty"`
	AccessIPv6 string `json:"accessIPv6,omitempty"`
}

// NewServer structures are used for both requests and responses.
// The fields discussed below are relevent for server-creation purposes.
//
// The Name field contains the desired name of the server.
// Note that (at present) Rackspace permits more than one server with the same name;
// however, software should not depend on this.
// Not only will Rackspace support thank you, so will your own devops engineers.
// A name is required.
//
// The ImageRef field contains the ID of the desired software image to place on the server.
// This ID must be found in the image slice returned by the Images() function.
// This field is required.
//
// The FlavorRef field contains the ID of the server configuration desired for deployment.
// This ID must be found in the flavor slice returned by the Flavors() function.
// This field is required.
//
// For OsDcfDiskConfig, refer to the Image or Server structure documentation.
// This field defaults to "AUTO" if not explicitly provided.
//
// Metadata contains a small key/value association of arbitrary data.
// Neither Rackspace nor OpenStack places significance on this field in any way.
// This field defaults to an empty map if not provided.
//
// Personality specifies the contents of certain files in the server's filesystem.
// The files and their contents are mapped through a slice of FileConfig structures.
// If not provided, all filesystem entities retain their image-specific configuration.
//
// Networks specifies an affinity for the server's various networks and interfaces.
// Networks are identified through UUIDs; see NetworkConfig structure documentation for more details.
// If not provided, network affinity is determined automatically.
//
// The AdminPass field may be used to provide a root- or administrator-password
// during the server provisioning process.
// If not provided, a random password will be automatically generated and returned in this field.
//
// The following fields are intended to be used to communicate certain results about the server being provisioned.
// When attempting to create a new server, these fields MUST not be provided.
// They'll be filled in by the response received from the Rackspace APIs.
//
// The Id field contains the server's unique identifier.
// The identifier's scope is best assumed to be bound by the user's account, unless other arrangements have been made with Rackspace.
//
// The SecurityGroup field allows the user to specify a security group at launch.
//
// Any Links provided are used to refer to the server specifically by URL.
// These links are useful for making additional REST calls not explicitly supported by Gorax.
type NewServer struct {
	Name            string                   `json:"name,omitempty"`
	ImageRef        string                   `json:"imageRef,omitempty"`
	FlavorRef       string                   `json:"flavorRef,omitempty"`
	Metadata        map[string]string        `json:"metadata,omitempty"`
	Personality     []FileConfig             `json:"personality,omitempty"`
	Networks        []NetworkConfig          `json:"networks,omitempty"`
	AdminPass       string                   `json:"adminPass,omitempty"`
	KeyPairName     string                   `json:"key_name,omitempty"`
	Id              string                   `json:"id,omitempty"`
	Links           []Link                   `json:"links,omitempty"`
	OsDcfDiskConfig string                   `json:"OS-DCF:diskConfig,omitempty"`
	SecurityGroup   []map[string]interface{} `json:"security_groups,omitempty"`
}

// ResizeRequest structures are used internally to encode to JSON the parameters required to resize a server instance.
// Client applications will not use this structure (no API accepts an instance of this structure).
// See the Region method ResizeServer() for more details on how to resize a server.
type ResizeRequest struct {
	Name       string `json:"name,omitempty"`
	FlavorRef  string `json:"flavorRef"`
	DiskConfig string `json:"OS-DCF:diskConfig,omitempty"`
}

type CreateImage struct {
	Name     string            `json:"name"`
	Metadata map[string]string `json:"metadata,omitempty"`
}
