// 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/racker/perigee"
)

// 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(),
			},
		})
	})
	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(),
			},
		})
	})
	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
}

// 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"`
}

// 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.
//
// 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     `json:"addresses"`
	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           interface{}    `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"`
}

// 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.
//
// 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        interface{}     `json:"metadata,omitempty"`
	Personality     []FileConfig    `json:"personality,omitempty"`
	Networks        []NetworkConfig `json:"networks,omitempty"`
	AdminPass       string          `json:"adminPass,omitempty"`
	Id              string          `json:"id,omitempty"`
	Links           []Link          `json:"links,omitempty"`
	OsDcfDiskConfig string          `json:"OS-DCF:diskConfig,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"`
}
