package gophercloud

// AccessProvider instances encapsulate a Keystone authentication interface.
type AccessProvider interface {
	// FirstEndpointUrlByCriteria searches through the service catalog for the first
	// matching entry endpoint fulfilling the provided criteria.  If nothing found,
	// return "".  Otherwise, return either the public or internal URL for the
	// endpoint, depending on both its existence and the setting of the ApiCriteria.UrlChoice
	// field.
	FirstEndpointUrlByCriteria(ApiCriteria) string

	// AuthToken provides a copy of the current authentication token for the user's credentials.
	// Note that AuthToken() will not automatically refresh an expired token.
	AuthToken() string

	// Revoke allows you to terminate any program's access to the OpenStack API by token ID.
	Revoke(string) error

	// Reauthenticate attempts to acquire a new authentication token, if the feature is enabled by
	// AuthOptions.AllowReauth.
	Reauthenticate() error
}

// ServiceCatalogerIdentityV2 interface provides direct access to the service catalog as offered by the Identity V2 API.
// We regret we need to fracture the namespace of what should otherwise be a simple concept; however,
// the OpenStack community saw fit to render V3's service catalog completely incompatible with V2.
type ServiceCatalogerForIdentityV2 interface {
	V2ServiceCatalog() []CatalogEntry
}

// CloudServersProvider instances encapsulate a Cloud Servers API, should one exist in the service catalog
// for your provider.
type CloudServersProvider interface {
	// Servers

	// ListServers provides a complete list of servers hosted by the user
	// in a given region.  This function differs from ListServersLinksOnly()
	// in that it returns all available details for each server returned.
	ListServers() ([]Server, error)

	// ListServers provides a complete list of servers hosted by the user
	// in a given region.  This function differs from ListServers() in that
	// it returns only IDs and links to each server returned.
	//
	// This function should be used only under certain circumstances.
	// It's most useful for checking to see if a server with a given ID exists,
	// or that you have permission to work with that server.  It's also useful
	// when the cost of retrieving the server link list plus the overhead of manually
	// invoking ServerById() for each of the servers you're interested in is less than
	// just calling ListServers() to begin with.  This may be a consideration, for
	// example, with mobile applications.
	//
	// In other cases, you probably should just call ListServers() and cache the
	// results to conserve overall bandwidth and reduce your access rate on the API.
	ListServersLinksOnly() ([]Server, error)

	// ServerById will retrieve a detailed server description given the unique ID
	// of a server.  The ID can be returned by either ListServers() or by ListServersLinksOnly().
	ServerById(id string) (*Server, error)

	// CreateServer requests a new server to be created by the cloud server provider.
	// The user must pass in a pointer to an initialized NewServerContainer structure.
	// Please refer to the NewServerContainer documentation for more details.
	//
	// If the NewServer structure's AdminPass is empty (""), a password will be
	// automatically generated by your OpenStack provider, and returned through the
	// AdminPass field of the result.  Take care, however; this will be the only time
	// this happens.  No other means exists in the public API to acquire a password
	// for a pre-existing server.  If you lose it, you'll need to call SetAdminPassword()
	// to set a new one.
	CreateServer(ns NewServer) (*NewServer, error)

	// DeleteServerById requests that the server with the assigned ID be removed
	// from your account.  The delete happens asynchronously.
	DeleteServerById(id string) error

	// SetAdminPassword requests that the server with the specified ID have its
	// administrative password changed.  For Linux, BSD, or other POSIX-like
	// system, this password corresponds to the root user.  For Windows machines,
	// the Administrator password will be affected instead.
	SetAdminPassword(id string, pw string) error

	// ResizeServer can be a short-hand for RebuildServer where only the size of the server
	// changes.  Note that after the resize operation is requested, you will need to confirm
	// the resize has completed for changes to take effect permanently.  Changes will assume
	// to be confirmed even without an explicit confirmation after 24 hours from the initial
	// request.
	ResizeServer(id, newName, newFlavor, newDiskConfig string) error

	// RevertResize will reject a server's resized configuration, thus
	// rolling back to the original server.
	RevertResize(id string) error

	// ConfirmResizeServer will acknowledge a server's resized configuration.
	ConfirmResize(id string) error

	// RebootServer requests that the server with the specified ID be rebooted.
	// Two reboot mechanisms exist.
	//
	// - Hard.  This will physically power-cycle the unit.
	// - Soft.  This will attempt to use the server's software-based mechanisms to restart
	//           the machine.  E.g., "shutdown -r now" on Linux.
	RebootServer(id string, hard bool) error

	// RescueServer requests that the server with the specified ID be placed into
	// a state of maintenance.  The server instance is replaced with a new instance,
	// of the same flavor and image.  This new image will have the boot volume of the
	// original machine mounted as a secondary device, so that repair and administration
	// may occur.  Use UnrescueServer() to restore the server to its previous state.
	// Note also that many providers will impose a time limit for how long a server may
	// exist in rescue mode!  Consult the API documentation for your provider for
	// details.
	RescueServer(id string) (string, error)

	// UnrescueServer requests that a server in rescue state be placed into its nominal
	// operating state.
	UnrescueServer(id string) error

	// UpdateServer alters one or more fields of the identified server's Server record.
	// However, not all fields may be altered.  Presently, only Name, AccessIPv4, and
	// AccessIPv6 fields may be altered.   If unspecified, or set to an empty or zero
	// value, the corresponding field remains unaltered.
	//
	// This function returns the new set of server details if successful.
	UpdateServer(id string, newValues NewServerSettings) (*Server, error)

	// RebuildServer reprovisions a server to the specifications given by the
	// NewServer structure.  The following fields are guaranteed to be recognized:
	//
	//		Name (required)				AccessIPv4
	//		imageRef (required)			AccessIPv6
	//		AdminPass (required)		Metadata
	//		Personality
	//
	// Other providers may reserve the right to act on additional fields.
	RebuildServer(id string, ns NewServer) (*Server, error)

	// CreateImage will create a new image from the specified server id returning the id of the new image.
	CreateImage(id string, ci CreateImage) (string, error)

	// Addresses

	// ListAddresses yields the list of available addresses for the server.
	// This information is also returned by ServerById() in the Server.Addresses
	// field.  However, if you have a lot of servers and all you need are addresses,
	// this function might be more efficient.
	ListAddresses(id string) (AddressSet, error)

	// ListAddressesByNetwork yields the list of available addresses for a given server id and networkLabel.
	// Example: ListAddressesByNetwork("234-4353-4jfrj-43j2s", "private")
	ListAddressesByNetwork(id, networkLabel string) (NetworkAddress, error)

	// ListFloatingIps yields the list of all floating IP addresses allocated to the current project.
	ListFloatingIps() ([]FloatingIp, error)

	// CreateFloatingIp allocates a new IP from the named pool to the current project.
	CreateFloatingIp(pool string) (FloatingIp, error)

	// DeleteFloatingIp returns the specified IP from the current project to the pool.
	DeleteFloatingIp(ip FloatingIp) error

	// AssociateFloatingIp associates the given floating IP to the given server id.
	AssociateFloatingIp(serverId string, ip FloatingIp) error

	// Images

	// ListImages yields the list of available operating system images.  This function
	// returns full details for each image, if available.
	ListImages() ([]Image, error)

	// ImageById yields details about a specific image.
	ImageById(id string) (*Image, error)

	// DeleteImageById will delete the specific image.
	DeleteImageById(id string) error

	// Flavors

	// ListFlavors yields the list of available system flavors.  This function
	// returns full details for each flavor, if available.
	ListFlavors() ([]Flavor, error)

	// KeyPairs

	// ListKeyPairs yields the list of available keypairs.
	ListKeyPairs() ([]KeyPair, error)

	// CreateKeyPairs will create or generate a new keypair.
	CreateKeyPair(nkp NewKeyPair) (KeyPair, error)

	// DeleteKeyPair wil delete a keypair.
	DeleteKeyPair(name string) error

	// ShowKeyPair will yield the named keypair.
	ShowKeyPair(name string) (KeyPair, error)

	// ListSecurityGroups provides a listing of security groups for the tenant.
	// This method works only if the provider supports the os-security-groups extension.
	ListSecurityGroups() ([]SecurityGroup, error)

	// CreateSecurityGroup lets a tenant create a new security group.
	// Only the SecurityGroup fields which are specified will be marshalled to the API.
	// This method works only if the provider supports the os-security-groups extension.
	CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error)

	// ListSecurityGroupsByServerId provides a list of security groups which apply to the indicated server.
	// This method works only if the provider supports the os-security-groups extension.
	ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error)

	// SecurityGroupById returns a security group corresponding to the provided ID number.
	// This method works only if the provider supports the os-security-groups extension.
	SecurityGroupById(id int) (*SecurityGroup, error)

	// DeleteSecurityGroupById disposes of a security group corresponding to the provided ID number.
	// This method works only if the provider supports the os-security-groups extension.
	DeleteSecurityGroupById(id int) error

	// ListDefaultSGRules lists default security group rules.
	// This method only works if the provider supports the os-security-groups-default-rules extension.
	ListDefaultSGRules() ([]SGRule, error)

	// CreateDefaultSGRule creates a default security group rule.
	// This method only works if the provider supports the os-security-groups-default-rules extension.
	CreateDefaultSGRule(SGRule) (*SGRule, error)

	// GetSGRule obtains information for a specified security group rule.
	// This method only works if the provider supports the os-security-groups-default-rules extension.
	GetSGRule(string) (*SGRule, error)
}
