package main

import (
	"crypto/rand"
	"fmt"
	"github.com/rackspace/gophercloud"
	"os"
	"time"
)

// getCredentials will verify existence of needed credential information
// provided through environment variables.  This function will not return
// if at least one piece of required information is missing.
func getCredentials() (provider, username, password, apiKey string) {
	provider = os.Getenv("SDK_PROVIDER")
	username = os.Getenv("SDK_USERNAME")
	password = os.Getenv("SDK_PASSWORD")
	apiKey   = os.Getenv("SDK_API_KEY")

	if (provider == "") || (username == "") || (password == "") {
		fmt.Fprintf(os.Stderr, "One or more of the following environment variables aren't set:\n")
		fmt.Fprintf(os.Stderr, "  SDK_PROVIDER=\"%s\"\n", provider)
		fmt.Fprintf(os.Stderr, "  SDK_USERNAME=\"%s\"\n", username)
		fmt.Fprintf(os.Stderr, "  SDK_PASSWORD=\"%s\"\n", password)
		os.Exit(1)
	}

	return
}

// randomString generates a string of given length, but random content.
// All content will be within the ASCII graphic character set.
// (Implementation from Even Shaw's contribution on
// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
func randomString(prefix string, n int) string {
	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	var bytes = make([]byte, n)
	rand.Read(bytes)
	for i, b := range bytes {
		bytes[i] = alphanum[b%byte(len(alphanum))]
	}
	return prefix + string(bytes)
}

// aSuitableImage finds a minimal image for use in dynamically creating servers.
// If none can be found, this function will panic.
func aSuitableImage(api gophercloud.CloudServersProvider) string {
	images, err := api.ListImages()
	if err != nil {
		panic(err)
	}

	// TODO(sfalvo):
	// Works for Rackspace, might not work for your provider!
	// Need to figure out why ListImages() provides 0 values for
	// Ram and Disk fields.
	//
	// Until then, just return Ubuntu 12.04 LTS.
	for i := 0; i < len(images); i++ {
		if images[i].Id == "23b564c9-c3e6-49f9-bc68-86c7a9ab5018" {
			return images[i].Id
		}
	}
	panic("Image 23b564c9-c3e6-49f9-bc68-86c7a9ab5018 (Ubuntu 12.04 LTS) not found.")
}

// aSuitableFlavor finds the minimum flavor capable of running the test image
// chosen by aSuitableImage.  If none can be found, this function will panic.
func aSuitableFlavor(api gophercloud.CloudServersProvider) string {
	flavors, err := api.ListFlavors()
	if err != nil {
		panic(err)
	}

	// TODO(sfalvo):
	// Works for Rackspace, might not work for your provider!
	// Need to figure out why ListFlavors() provides 0 values for
	// Ram and Disk fields.
	//
	// Until then, just return Ubuntu 12.04 LTS.
	for i := 0; i < len(flavors); i++ {
		if flavors[i].Id == "2" {
			return flavors[i].Id
		}
	}
	panic("Flavor 2 (512MB 1-core 20GB machine) not found.")
}

// createServer creates a new server in a manner compatible with acceptance testing.
// In particular, it ensures that the name of the server always starts with "ACPTTEST--",
// which the delete servers acceptance test relies on to identify servers to delete.
// Passing in empty image and flavor references will force the use of reasonable defaults.
// An empty name string will result in a dynamically created name prefixed with "ACPTTEST--".
// A blank admin password will cause a password to be automatically generated; however,
// at present no means of recovering this password exists, as no acceptance tests yet require
// this data.
func createServer(servers gophercloud.CloudServersProvider, imageRef, flavorRef, name, adminPass string) (string, error) {
	if imageRef == "" {
		imageRef = aSuitableImage(servers)
	}

	if flavorRef == "" {
		flavorRef = aSuitableFlavor(servers)
	}

	if len(name) < 1 {
		name = randomString("ACPTTEST", 16)
	}

	if (len(name) < 8) || (name[0:8] != "ACPTTEST") {
		name = fmt.Sprintf("ACPTTEST--%s", name)
	}

	newServer, err := servers.CreateServer(gophercloud.NewServer{
		Name:      name,
		ImageRef:  imageRef,
		FlavorRef: flavorRef,
		AdminPass: adminPass,
	})

	if err != nil {
		return "", err
	}

	return newServer.Id, nil
}

// findAlternativeFlavor locates a flavor to resize a server to.  It is guaranteed to be different
// than what aSuitableFlavor() returns.  If none could be found, this function will panic.
func findAlternativeFlavor() string {
	return "3" // 1GB image, up from 512MB image
}

// findAlternativeImage locates an image to resize or rebuild a server with.  It is guaranteed to be
// different than what aSuitableImage() returns.  If none could be found, this function will panic.
func findAlternativeImage() string {
	return "c6f9c411-e708-4952-91e5-62ded5ea4d3e"
}

// withIdentity authenticates the user against the provider's identity service, and provides an
// accessor for additional services.
func withIdentity(ar bool, f func(gophercloud.AccessProvider)) {
	provider, username, password, _ := getCredentials()
	acc, err := gophercloud.Authenticate(
		provider,
		gophercloud.AuthOptions{
			Username:    username,
			Password:    password,
			AllowReauth: ar,
		},
	)
	if err != nil {
		panic(err)
	}

	f(acc)
}

// withServerApi acquires the cloud servers API.
func withServerApi(acc gophercloud.AccessProvider, f func(gophercloud.CloudServersProvider)) {
	api, err := gophercloud.ServersApi(acc, gophercloud.ApiCriteria{
		Name:      "cloudServersOpenStack",
		VersionId: "2",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		panic(err)
	}

	f(api)
}

// waitForServerState polls, every 10 seconds, for a given server to appear in the indicated state.
// This call will block forever if it never appears in the desired state, so if a timeout is required,
// make sure to call this function in a goroutine.
func waitForServerState(api gophercloud.CloudServersProvider, id, state string) error {
	for {
		s, err := api.ServerById(id)
		if err != nil {
			return err
		}
		if s.Status == state {
			return nil
		}
		time.Sleep(10 * time.Second)
	}
	panic("Impossible")
}

// waitForImageState polls, every 10 seconds, for a given image to appear in the indicated state.
// This call will block forever if it never appears in the desired state, so if a timeout is required,
// make sure to call this function in a goroutine.
func waitForImageState(api gophercloud.CloudServersProvider, id, state string) error {
	for {
		s, err := api.ImageById(id)
		if err != nil {
			return err
		}
		if s.Status == state {
			return nil
		}
		time.Sleep(10 * time.Second)
	}
	panic("Impossible")
}
