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

// 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},
			DumpReqJson: true,
		})
	})

	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
}

// 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"`
	KeyPairName     string          `json:"key_name,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"`
}

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